cf_438_C Qualification Rounds

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/LSC_333/article/details/78164818

Snark and Philip are preparing the problemset for the upcoming pre-qualification round for semi-quarter-finals. They have a bank of nproblems, and they want to select any non-empty subset of it as a problemset.

k experienced teams are participating in the contest. Some of these teams already know some of the problems. To make the contest interesting for them, each of the teams should know at most half of the selected problems.

Determine if Snark and Philip can make an interesting problemset!

Input

The first line contains two integers nk (1 ≤ n ≤ 1051 ≤ k ≤ 4) — the number of problems and the number of experienced teams.

Each of the next n lines contains k integers, each equal to 0 or 1. The j-th number in the i-th line is 1 if j-th team knows i-th problem and 0otherwise.

Output

Print "YES" (quotes for clarity), if it is possible to make an interesting problemset, and "NO" otherwise.

You can print each character either upper- or lowercase ("YeS" and "yes" are valid when the answer is "YES").

Examples
input
5 3
1 0 1
1 1 0
1 0 0
1 0 0
1 0 0
output
NO
input
3 2
1 0
1 1
0 1
output
YES
Note

In the first example you can't make any interesting problemset, because the first team knows all problems.

In the second example you can choose the first and the third problems.


扫描二维码关注公众号,回复: 5279804 查看本文章

题意:

给n个题目和k支队伍,每只队伍都可能已经知道一些题目,现在求是否能找出几个(也可以是一个)题目,使得每只队伍最多只了解这些题目中的一半。

输入的第i行第j列代表第j支队伍是否了解第i题,1是了解,0是不了解


思路:

刚开始瞎搞,结果卡在第10个测试点。。。

正解是状态压缩加枚举。。。orz

可以知道,如果能够找出,则必然最少有两题(一题的情况是都为0,和两题的意思一样)满足

那么将每个题目的了解情况压缩成一个十进制数,然后依次去做按位与,如果等于0,就能找出,否则不能。

由于k<=4,所以压缩后的值顶多为15,即有16种状态,这样就可以暴力枚举了


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <algorithm>
#include <vector>
#include <stack>
#define INF 0x3f3f3f3f
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
int n, k;
bool a[1<<4+5];
int main()
{
    while(~scanf("%d%d", &n, &k))
    {
        memset(a, false, sizeof(a));
        for(int i=1; i<=n; i++)
        {
            int sum=0;
            for(int j=0; j<k; j++)
            {
                int x;
                scanf("%d", &x);
                sum+=(1<<j)*x;   //压缩
            }
            a[sum]=true;
        }
        bool flag=false;
        for(int i=0; i<16; i++)    //枚举
        {
            if(!a[i])
                continue;
            for(int j=0; j<16; j++)
            {
                if(!a[j])
                    continue;
                if((i&j)==0)
                {
                    flag=true;
                    break;
                }
            }
            if(flag)
                break;
        }
        if(flag)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}




猜你喜欢

转载自blog.csdn.net/LSC_333/article/details/78164818