http://codeforces.com/problemset/problem/868/C
给出一张01图,横行表示题目数,列表示队伍且最大只有4,1表示该队伍知道该题。0则相反,问能否找出一些题目使得每个队伍知道的题目数不超过题目总数的一半
该题关键在于事实上如果真的能挑出这些题目,其实只要有2道题就可以了。于是就可以用二进制了,将1到4队伍标记为1 2 4 8,那么如果某道题为9 则肯定是 1+8,那就意味着第1,4队伍知道这道题,而2,3不知道。那么既然是找2道题,那么只要找知道这2道题的队伍没有重复的情况即可,假设最复杂的情况就是4只队伍,那么只要找2道题分别是3和12 6和10 9和6即可。因为一个数用二进制来表示总是唯一的。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,k;
while(cin>>n>>k)
{
int tm[22];
int ts[22];
int i,j;
memset(tm,0,sizeof(tm));
memset(ts,0,sizeof(ts));
for(i=1;i<=n;i++)
{
int lm=0;
int bin=1;
int _y;
for(j=1;j<=k;j++)
{
cin>>_y;
lm+=_y*bin;
bin*=2;
if(_y==0)ts[j]++;
}
tm[lm]++;
}
if(tm[0]!=0)
{
cout<<"YES"<<endl;
continue;
}
int flag=0;
for(i=1;i<=k;i++)
{
if(ts[i]==0)
{
flag=1;
break;
}
}
if(flag==1){
cout<<"NO"<<endl;
continue;
}
if(k==1||k==2){
cout<<"YES"<<endl;
continue;
}
if(k==3){
if(tm[1]||tm[2]||tm[4])cout<<"YES"<<endl;
else cout<<"NO"<<endl;
continue;
}
if(tm[1]||tm[2]||tm[4]||tm[8]){
cout<<"YES"<<endl;
continue;
}
if(tm[3]&&tm[12]){
cout<<"YES"<<endl;
continue;
}
if(tm[5]&&tm[10]){
cout<<"YES"<<endl;
continue;
}
if(tm[9]&&tm[6]){
cout<<"YES"<<endl;
continue;
}
cout<<"NO"<<endl;
}
return 0;
}