每 一 行 都 要 填 充 a 个 1 , 所 以 我 们 应 该 填 充 满 足 一 个 条 件 每一行都要填充a个1,所以我们应该填充满足一个条件 a1,

尽 可 能 让 每 一 列 的 1 均 衡 , 否 则 会 出 现 某 一 列 的 1 太 多 或 太 少 \color{Red}尽可能让每一列的1均衡,否则会出现某一列的1太多或太少 1,1

那 么 这 里 有 两 种 做 法 那么这里有两种做法

Ⅰ . 暴 力 , 对 于 每 次 填 充 的 数 , 循 环 找 出 哪 一 列 的 1 最 少 , 填 上 去 Ⅰ.暴力,对于每次填充的数,循环找出哪一列的1最少,填上去 .,,1,

Ⅱ . 思 维 , 让 每 列 均 衡 , 所 以 当 前 行 的 第 一 个 1 填 在 上 一 行 最 后 一 个 1 后 面 的 列 Ⅱ.思维,让每列均衡,所以当前行的第一个1填在上一行最后一个1后面的列 .,,11

也 就 是 每 次 p = ( p + 1 ) % m , 每 次 填 在 第 j 列 也就是每次p=(p+1)\%m,每次填在第j列 p=(p+1)%m,j

下 面 是 暴 力 的 方 法 下面是暴力的方法

#include <bits/stdc++.h>
using namespace std;
#define p(a,b) make_pair(a,b)
int vis[56],a[56][56],cnt[56];
int t,n,m,q,w;
int main()
{
	cin >> t;
	while(t--)
	{
		cin >> n >> m >> q >> w;
		if(q*n!=w*m||q>m||w>n)
		{
			cout << "NO" <<endl;
			continue;
		}
		memset(a,0,sizeof(a));
		memset(cnt,0,sizeof(cnt));
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++)	vis[j]=0;
			for(int j=1;j<=q;j++)
			{
				int shu=1e9,num=-1;
				for(int s=1;s<=m;s++)
				{
					if(vis[s])	continue;
					if(shu>cnt[s])
						shu=cnt[s],num=s;	
				}
				vis[num]=1,a[i][num]=1,cnt[num]++;	
			} 
		}
		cout<<"YES"<<endl;
		for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			cout<<a[i][j];
			if(j==m)	cout<<endl;
		}
	}
}