PKU-3600 Subimage Recognition
問題概要
0と1からなる二つの画像A,Bが与えられる.
Bの任意の行と列を消して画像Aが作り出せるかを求めよ.
解法
行の消し方を全部調べると,列の消し方は貪欲に求めることが出来る.
行の消し方は20C10なので20C10*20*20で十分間に合う.
実装
#include <cstdio> #include <iostream> #include <algorithm> #include <bitset> #include <set> using namespace std; int r,c; int MAP[20][20]; int R,C; int image[20][20]; #define REP(i,x)for(int i=0;i<(int)x;i++) int ans=0; bool used_row[20]; bool comp_col(int x,int y){ int cnt=0; REP(i,R){ if(used_row[i]==false)continue; if(MAP[cnt][x]!=image[i][y])return false; cnt++; } return true; } bool solve(){ int now=0; REP(i,C){ if(now>=c)break; if(comp_col(now,i))now++; } if(now==c)return true; return false; } void dfs(int x,int count){ if(count>r)return; if(x==R){ if(count==r){ /* cout<<"!"<<endl; REP(i,R){ cout<<used_row[i]; } cout<<endl;*/ if(solve()){ ans=true; } } return; } used_row[x]=1; dfs(x+1,count+1); if(ans)return; used_row[x]=0; dfs(x+1,count); if(ans)return; } int main() { cin>>r>>c; REP(i,r){ string in; cin>>in; REP(j,c){ MAP[i][j]=(in[j]=='1'); } } cin>>R>>C; REP(i,R){ string in; cin>>in; REP(j,C){ image[i][j]=(in[j]=='1'); } } dfs(0,0); if(ans){ cout<<"Yes"<<endl; }else{ cout<<"No"<<endl; } return 0; }