题目链接
https://ac.nowcoder.com/acm/contest/7501/J
题目大意
给一个nm的矩阵 每次对ab大小的子矩阵上每个位置减一
问是否能将这个矩阵每个位置上的值都变成0
题目思路
这题就用最简单的思路
遍历整个数组 在每个位置判断它是否大于0
大于则对从他开始的a*b矩阵减去它本身的值
小于就标记退出循环
但是如果用暴力直接写的话肯定会t
所以用二维差分来维护每个位置的值
至于二维差分可以看这个博客
https://blog.csdn.net/justidle/article/details/104506724
ac代码
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <utility>
#define pi 3.1415926535898
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
#define eps 1e-6
#define ms(a,b) memset(a,b,sizeof(a))
#define legal(a,b) a&b
#define print1 printf("111\n")
using namespace std;
const int maxn = 5e3+10;
const int inf = 0x1f1f1f1f;
const int mod = 2333;
int gcd(int x,int y)
{
return y?gcd(y,x%y):x;
}
int lcm(int x,int y)
{
return x/gcd(x,y)*y;
}
int mp[maxn][maxn],q[maxn],a[maxn][maxn],p[maxn][maxn];
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
int _;
scanf("%d",&_);
while(_--)
{
int n,m,x,y;
scanf("%d%d%d%d",&n,&m,&x,&y);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
p[i][j]=0;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
p[i][j]=a[i][j]-a[i-1][j]-a[i][j-1]+a[i-1][j-1];
}
}
int flag=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
a[i][j]=p[i][j]+p[i-1][j]+p[i][j-1]-p[i-1][j-1];
if(p[i][j]!=0)
{
if(p[i][j]<0)
{
flag=1;
//printf("11 %d %d\n",i,j);
break;
}else
{
if(i+x-1>n||j+y-1>m)
{
flag=1;//printf("22 %d %d\n",i,j);
break;
}
p[i][j]-=a[i][j];
p[i][j+y]+=a[i][j];
p[i+x][j]+=a[i][j];
p[i+x][j+y]-=a[i][j];
}
}
}
}
if(flag==1)
printf("QAQ\n");
else
printf("^_^\n");
}
}