Codeforces 868C Qualification Rounds

来源:互联网 发布:淘宝差评拦截在哪设置 编辑:程序博客网 时间:2024/05/21 06:01

C. Qualification Rounds

time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard 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 ≤ 1e5, 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

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.


题意:
有n(<=1e5)道题目,k(<=4)名选手,每个选手知道一些题目的答案,问是否可能挑出一些题目作为problemset,使每名选手知道的题目最多不超过problemset的一半。

思路:
一开始把数据范围看反了,觉得很简单就拿位运算暴力来了一发,还觉得美滋滋,然后滚粗了啊。仔细看了题目之后才发现问题。然后一看题目数是1e5没法暴力啊,然后就僵硬了啊。
搜了题解才知道如果能选出这样一个problemset,则一定能选出只有两道题目的problemset。即一个符合题意的problemset中一定有两道题目不能被任何选手同时解决。不过这个我还没想出来该怎么证啊。
把每行数据都用一个二进制数表示,丢进set里,然后枚举一下看有没有两个(可以是同一个数)与起来为零的。

代码:

#include<bits/stdc++.h>using namespace std;int n,k;set <int> s;bool solve(){    set <int>::iterator i,j;    for(i=s.begin();i!=s.end();i++)    {        for(j=s.begin();j!=s.end();j++)        {            if(!((*i)&(*j))) return 1;        }    }    return 0;}int main(){    while(~scanf("%d%d",&n,&k))    {        s.clear();        int i,j;        for(i=0;i<n;i++)        {            int x=0;            for(j=0;j<k;j++)            {                int a;                scanf("%d",&a);                x|=(a<<j);            }            s.insert(x);        }        if(solve()) printf("YES\n");        else printf("NO\n");    }}
原创粉丝点击