POJ 3740

思路:二进制枚举,再用位运算来判断选的那些行是否满足每列只有一个1,(很神奇的位运算)。考虑最多16行,因此可以用一个int型(32位>16)的每个二进制位来表示每列状态,比如某列的第二行有个1,则int型数字里面第二个二进制位就为1,时间复杂度2^16*m,可以接受。这里存在一个问题就是怎么通过每列的状态(一个int型的数,设为col[j])来判断这一列是否含有一个1呢?可以这么做,令t = col[j]&i(i表示枚举的行的二进制状态),这样就把枚举的行里面的1取了出来,如果t=0,说明枚举的这些行对应的某列里面一个1都不含,那么就不满足条件,如果t不等于0呢?那么还要考察这列里面是不是只含一个1,可以让t&(t-1),等于0就是一个1,否则不是!

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 333
using namespace std; 
int col[MAXN]; 
int main(){
    int n, m, tmp; 
    freopen("in.c", "r", stdin); 
    while(~scanf("%d%d", &n, &m)){
        int flag = 0;
        memset(col, 0, sizeof(col)); 
        for(int i = 0; i < n; i ++){
            for(int j = 0; j < m; j ++){
                scanf("%d",&tmp); 
                if(tmp) col[j] += (1 << i); 
                if(i == n-1 && col[j] == 0) flag = 1; 
            }
        }
        if(flag){printf("It is impossible\n"); continue;}
        for(int i = 1; i < (1 << n); i ++){
            int tmp = 0; 
            for(int j = 0; j < m; j ++){
                int t = col[j] & i; 
                if(t == 0 || (t & (t-1))) {
                    tmp = 1; 
                    break; 
                }
            }
            if(!tmp) {flag = 1; break; } 
        }
        printf(flag == 0 ? "It is impossible\n":"Yes, I found it\n"); 
    }
    return 0; 
}



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值