题意:给一个小矩形,一个大矩形,均是01矩阵,然后问从大矩形中删除一些行一些列是否能得到小矩形。
题解:先枚举小矩形由大矩形哪些列组成,然后在判断这些列能否组成小矩形,判断方法为:先将小矩形每一行当做2进制数存入一个一维数组中(长r),在对每一个已经枚举好的大矩形的列也同样按此操作,得到一个长为R的数组,如果第一个数组是第二个数组的子序列,那么就是可行的。这样,枚举列的复杂度O(Choose(C,c)),至多十几万,判断子序列是O(r+R)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int r,c,R,C; 6 int chs[25],rm[25]; 7 char map[25][25]; 8 bool solve() 9 { 10 int RM[25],i,j; 11 for(i=0;i<R;i++) 12 { 13 int tp=0; 14 for(j=0;j<c;j++) 15 tp=tp*2+(map[i][chs[j]]=='1'); 16 RM[i]=tp; 17 } 18 for(i=0,j=0;i<r&&j<R;j++) 19 { 20 if(rm[i]==RM[j]) 21 i++; 22 } 23 return i==r; 24 } 25 bool dfs(int k,int cnt) 26 { 27 if(C-k==c-cnt) 28 { 29 while(k<C) 30 chs[cnt++]=k++; 31 return solve(); 32 } 33 else if(k==C) 34 return false; 35 if(dfs(k+1,cnt)) 36 return true; 37 chs[cnt]=k; 38 return dfs(k+1,cnt+1); 39 } 40 int main() 41 { 42 while(scanf("%d%d",&r,&c)!=EOF) 43 { 44 for(int i=0;i<r;i++) 45 { 46 char ss[30]; 47 int tp=0; 48 scanf("%s",ss); 49 for(int j=0;j<c;j++) 50 { 51 tp=tp*2+(ss[j]=='1'); 52 } 53 rm[i]=tp; 54 } 55 scanf("%d%d ",&R,&C); 56 for(int i=0;i<R;i++) 57 scanf(" %s",map[i]); 58 if(dfs(0,0)) 59 printf("Yes\n"); 60 else 61 printf("No\n"); 62 } 63 return 0; 64 }