zoukankan      html  css  js  c++  java
  • 【Codeforces】868C. Qualification Rounds

    【题目】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
  • 相关阅读:
    CPU飙高,OOM排查?
    反射
    Mybatits
    spring 基础问题
    java中格式化数字0和#区别
    java中File对象的mkdir和mkdirs的区别
    java截取字符串几种方式
    java工厂模式
    Java获取文件路径的几种方式
    jxl生成excel时,增加批注和冻结窗口
  • 原文地址:https://www.cnblogs.com/onioncyc/p/7630188.html
Copyright © 2011-2022 走看看