题意
给出n,m,x,y,要求构造一个n*m的矩形使得其元素和大于0且任意一个x*y的子矩形的元素和小于0。
x,y,n,m<=500
分析
很容易想到在所有横坐标为x的倍数,纵坐标为y的倍数的格子填上-x*y,其余格子全填1,这样就可以保证每个子矩阵的和小于0。但是这样在多出来的格子比较少的时候可能会导致整个矩形的元素和小于0。于是我们可以设一个较大的常数d,把每个格子填上d,每个关键格子填上-(x*y-1)*d+1即可。
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=505;
const int d=4000;
int n,m,x,y,a[N][N];
int main()
{
scanf("%d%d%d%d",&n,&m,&x,&y);
if (n%x==0&&m%y==0) {puts("No");return 0;}
puts("Yes");
for (int i=x;i<=n;i+=x)
for (int j=y;j<=m;j+=y)
a[i][j]=-x*y*d+d-1;
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++) printf("%d ",!a[i][j]?d:a[i][j]);
puts("");
}
return 0;
}