• 【hrbust2294】方方正正


    题意

    哈理工2016级新生程序设计全国邀请赛C题
    一个r行c列的01矩阵,告诉你每行的和、每列的和,问是否存在这样的矩阵?

    题解

    首先,行和和列和之和要相等,否则一定是NO。
    然后根据Gale-Ryser定理判断存在性:

    求出(R^*=(r_1^*,r_2^*,...,r_m^*),r_i^*=行和大于等于i的行数)
    只要(R^*preceq S)就存在,这里的S就是列和向量。
    二元操作符(preceq)的定义是:向量x的前i大的数之和总是比向量y的前i大的数之和要小或者相等,那么(xpreceq y)

    代码

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define N 100006
    int i,m,n;
    long long rs,cs,r[N],c[N],w[N];
    int main(){
        while(~scanf("%d%d",&m,&n)){//m行n列
            rs=cs=0;
            memset(w,0,sizeof w);
    
            for(i=1;i<=m;i++){
                scanf("%d",&r[i]);
                rs+=r[i];
                w[r[i]]++;//w[i]:行和为i的有几个
            }
    
            for(i=1;i<=n;i++){
                scanf("%d",&c[i]);
                cs+=c[i];
            }
    
            if(rs!=cs){
                puts("NO");
                continue;
            }
    
            sort(c+1,c+1+n,greater<long long>());
    
            for(i=n;i;i--)w[i]+=w[i+1];//w[i]:行和大于等于i的有几个
    
            for(i=1;i<=n;i++){
                c[i]+=c[i-1];
                w[i]+=w[i-1];
                if(c[i]>w[i])//w就是R*,若c[i]>w[i]表明R*不能盖过S
                    break;
            }
    
            if(i==n+1) puts("YES");
            else puts("NO");
        }
        return 0;
    }
    
  • 相关阅读:
    Redis主从同步分析
    团队形成的四个阶段
    Firefox 按一下Alt键 出现菜单!
    Android系统手机端抓包方法
    你必须知道的EF知识和经验
    .NET异步编程之回调
    正确设置电脑虚拟内存
    Cache and Virtual Memory
    性能测试指标
    HTTP协议
  • 原文地址:https://www.cnblogs.com/flipped/p/6213178.html
Copyright © 2020-2023  润新知