【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大的数之和要小或者相等,那么\(x\preceq 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;
}
┆凉┆暖┆降┆等┆幸┆我┆我┆里┆将┆ ┆可┆有┆谦┆戮┆那┆ ┆大┆始┆ ┆然┆
┆薄┆一┆临┆你┆的┆还┆没┆ ┆来┆ ┆是┆来┆逊┆没┆些┆ ┆雁┆终┆ ┆而┆
┆ ┆暖┆ ┆如┆地┆站┆有┆ ┆也┆ ┆我┆ ┆的┆有┆精┆ ┆也┆没┆ ┆你┆
┆ ┆这┆ ┆试┆方┆在┆逃┆ ┆会┆ ┆在┆ ┆清┆来┆准┆ ┆没┆有┆ ┆没┆
┆ ┆生┆ ┆探┆ ┆最┆避┆ ┆在┆ ┆这┆ ┆晨┆ ┆的┆ ┆有┆来┆ ┆有┆
┆ ┆之┆ ┆般┆ ┆不┆ ┆ ┆这┆ ┆里┆ ┆没┆ ┆杀┆ ┆来┆ ┆ ┆来┆