POJ 3600

题意:给一个小矩形,一个大矩形,均是01矩阵,然后问从大矩形中删除一些行一些列是否能得到小矩形。

题解:先枚举小矩形由大矩形哪些列组成,然后在判断这些列能否组成小矩形,判断方法为:先将小矩形每一行当做2进制数存入一个一维数组中(长r),在对每一个已经枚举好的大矩形的列也同样按此操作,得到一个长为R的数组,如果第一个数组是第二个数组的子序列,那么就是可行的。这样,枚举列的复杂度O(Choose(C,c)),至多十几万,判断子序列是O(r+R)

View Code
 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 }

转载于:https://www.cnblogs.com/tmeteorj/archive/2012/10/05/2712433.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值