码迷,mamicode.com
首页 > 其他好文 > 详细

【Codeforces】868C. Qualification Rounds

时间:2017-10-05 23:09:49      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:display   space   cat   题解   说明   get   contest   偶数   gif   

【题目】C. Qualification Rounds

【题意】给定n个问题和K个人,给定每个人知道的问题列表,求能否找到一个非空问题集合,满足每个人知道的集合中问题数量都不超过集合总题数的一半。n<=10^5,k<=4。

【算法】数学结论

【题解】当k<=4时,结论:若存在合法方案,则一定存在选择2个问题的合法方案

证明:对于选择偶数个问题的合法方案(奇数不优),假设方案中每个人都知道一半问题(最坏),试图从中得到选择2个问题的合法方案。

先得到三条易证的结论:

Ⅰ两个人知道区间互补,则找不到问题满足这两个人都不知道。

Ⅱ否则,至少存在一个问题满足这两个人都不知道。

Ⅲ多个人知道区间一致,则至少存在一个问题满足这多个人都不知道。

①若不存在Ⅰ,则把4个人分成2组,每组内由Ⅱ可得1个问题。如果2个问题一致说明这两人对应那两人区间分别一致,由Ⅲ可知交换搭档即可。

②若存在Ⅰ,则把互补分到不同组。若一个人和另外三个人都互补,另外三个人由Ⅲ得到1个问题,一个人再得到1个问题。

得证。

技术分享
#include<cstdio>
#include<cstring>
#include<cctype>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
int read(){
    char c;int s=0,t=1;
    while(!isdigit(c=getchar()))if(c==-)t=-1;
    do{s=s*10+c-0;}while(isdigit(c=getchar()));
    return s*t;
}
/*------------------------------------------------------------*/
const int inf=0x3f3f3f3f;

int n,kind,a[100010];
bool c[10000];

int main(){
    n=read();kind=read();
    for(int i=1;i<=n;i++){
        for(int j=1;j<=kind;j++)a[i]=(a[i]<<1)+read();
        c[a[i]]=1;
    }
    if(c[0]){printf("YES");return 0;}
    for(int i=1;i<(1<<kind);i++)if(c[i]){
        int x=i^((1<<kind)-1);
        for(int j=1;j<(1<<kind);j++)if(c[j]&&(x&j)==j){printf("YES");return 0;}
    }
    printf("NO");
    return 0;
}
View Code

 

【Codeforces】868C. Qualification Rounds

标签:display   space   cat   题解   说明   get   contest   偶数   gif   

原文地址:http://www.cnblogs.com/onioncyc/p/7630188.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!