Codeforces round438 C. Qualification Rounds

题目:
n个题目,k个队伍,每个队伍知晓其中某些题目,问能否选出一些题目,使得每个队伍知晓的题目不超过一半
(1 ≤ n ≤ 105, 1 ≤ k ≤ 4)
分析:
一、若选出了3个题目,每个队伍至多知晓其中1个,那么去掉知晓队伍数最多的那个题目,仍为可行解,所以选出的3个题目其实是选出两个题目的扩增
二、若选出了4个题目
1、k=1时,能选出4个题目说明至少有2个题目是这个队伍不知晓的,所以可以选出2个题目使条件仍成立
2、k=2时,能选出4个题目说明,在选出的4个题目中,每个队伍至少有两个题目是不知晓的,同时删除1队和2队分别知晓的1个题目(也有可能是1队2队同时知晓的某个题目),删除这两个题目后,仍然满足条件
3、k=3时,能选出4个题目说明,在选出的4个题目中,每个队伍至少有两个题目是不知晓的。若3队不知晓任何题目,与k=2等价。若3队至少知晓1个题目,首先删除3队知晓的一个题目,这个题目可能同时被1队或2队知晓,假设被1队知晓,我们只需再删除一个被二队知晓的题目即可,又回到2个题目的情况,仍满足
4、k=4时,能选出4个题目说明,在选出的4个题目中,每个队伍至少有两个题目是不知晓的。若4队不知晓任何题目…………同理可证仍可化简为2个题目的情况
三、若选出了5个题目,每个队伍至多知道其中2个,则删除其中知晓人数最多的一个题目,仍满足,也就是回到选出4个题目的情况,所以仍可化简为2个题目

以此类推,若选出n个题目符合题意,总可选出2个题目也符合题意。
所以我们用二进制表示每个题目是否被某个队伍知晓,对每个题目,寻找是否存在一个题目,按位与之后==0,若存在则输出YES
代码:

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int Tmax=100005;
int n,k,s[Tmax];
bool v[Tmax];
int main()
{
    int i,j,tmp,sum;
    scanf("%d%d",&n,&k);
    for(i=1;i<=n;i++)
    {
        sum=0;
        for(j=0;j<k;j++)
        {
            scanf("%d",&tmp);
            sum+=tmp<<j;
        }
        s[i]=sum;
        v[sum]=true;
    }
    for(i=1;i<=n;i++)
    {
        for(j=0;j<=31;j++)
          if((s[i]&j)==0&&v[j]==true) 
          {
             printf("YES");
             return 0;
          }
    }
    printf("NO");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值