您的位置:首页 > 其它

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

2017-10-17 14:53 351 查看
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
4000
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");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: