题目链接
题目大意:
构造一个n行m列矩阵的01矩阵,使得每行都有a个1且每列都有b个1。如果不存在就输出“NO”,存在就输出“YES”和构造的矩阵。
解题思路:
不能构造的矩阵就一种情况就是
n
∗
a
≠
m
∗
b
n*a \neq m*b
n∗a=m∗b。其中每行都有a个1,且每列个数都相同,所以我们只要想一种情况能够使构造的每列的1的数量都相同,那就符合情况。所以我们想到每一行都是一段连续的长度为a的1(这就满足每一行都相同且为a的条件),然后每一行都相对于上一行进行移动,移动距离为d,则只需要满足
d
∗
n
m
o
d
m
=
=
0
{d*n}\bmod m==0
d∗nmodm==0 就能使每一列的1的个数都相同(可以画图感受一下),此时每列数即为n*a/m=b,即就是构造结果了。
解题代码:
#include<bits/stdc++.h>
using namespace std;
mt19937 rng_32(chrono::steady_clock::now().time_since_epoch().count());
typedef long long ll;
const int maxn=2e5+10;
int n,m,a,b;
char s[55][55];
int main()
{
int cas;
cin>>cas;
while (cas--)
{
scanf("%d%d%d%d",&n,&m,&a,&b);
if (a*n != b*m)
{
cout<<"NO\n";
continue;
}
memset(s,0,sizeof(s));
int d=0;
for (d=1;d<=a;d++)
{
if (n*d%m==0)
break;
}
int cur=0;
for (int i=0;i<n;i++)
{
for (int j=0;j<a;j++)
s[i][(cur+j)%m]='1';
cur=(cur+d)%m;
}
for (int i=0;i<n;i++)
{
for (int j=0;j<m;j++)
{
if (!s[i][j])
s[i][j]='0';
}
}
cout<<"YES\n";
for (int i=0;i<n;i++)
cout<<s[i]<<endl;
}
return 0;
}