problem/868/C Qualification Rounds 思维题 状态压缩 暴力枚举

来源:互联网 发布:c语言游戏引擎 编辑:程序博客网 时间:2024/05/22 01:31

C. Qualification Rounds
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Snark and Philip are preparing the problemset for the upcoming pre-qualification round for semi-quarter-finals. They have a bank of n problems, 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 n, k (1 ≤ n ≤ 105, 1 ≤ 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 0 otherwise.
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
【题意】

现在有k支队伍要参加一个比赛,题库中有n道题目,其中有些队伍已经知道了某些题目,现在给出每道题目每支队伍是否知道的情况,问是否存在一套题目使得所有队伍最多只知道一半的题目。
【思路】
很有意思的一道题。我们可以一步一步递推。
如果合法问题集里只有一个问题 那么这个问题的二进制表达一定为0000
如果合法问题集里只有两个问题 那么这两个问题 的按位与肯定为0
再来考虑必须要三个问题的情况, 可以很轻易的发现,这种情况不存在。
再考虑要4个问题的情 那么这个问题里的任意三个问题至少有一只队至少知道其中两个
既每一位可以为 1/3 ,2/3 ,0 以1/3 2/3 2/3 0 为例。 这时 如果有符合条件的问题,我们那么这个问题的二进制表达最差也会是1 0 0 1. 通过枚举 我们发现 原来的三个问题中至少有一个问题可以表示为0110.
然后以此 类推
所以我们只要枚举符合问题数小于2的问题集就行了。 利用二进制压缩进行枚举。 问题种类最多位2^4种 所以只要枚举16*16次就行了。
被智商碾压。。。。

#include<stdio.h>#include<iostream>#include<algorithm>#include<string.h>#include<vector>using namespace std;const int MAX=1e5+10;int pro[MAX];int main(){    int flag=0;    int n,k;    scanf("%d %d",&n,&k);    for(int i=0;i<n;i++)    {        int cnt=0;        for(int j=0;j<k;j++)        {            cnt<<=1;            int temp;            scanf("%d",&temp);            cnt|=temp;        }        pro[cnt]=1;        if(cnt==0) flag=1;    }    for(int i=0;i<(1<<k);i++)    {        if(pro[i]==0)            continue;        for(int j=0;j<(1<<4);j++)        {            if(pro[j]==0)                continue;            if(!(i&j))            {                flag=1;                //cout<<i<<" "<<j<<endl;            }        }    }    if(!flag)        puts("NO");    else        puts("YES");}
阅读全文
0 0