链接:https://ac.nowcoder.com/acm/contest/7501/J?&headNav=acm
Given a matrix M of size n×m and two integers a, b , determine weither it is possible to make all entrys of M zero by repeatedly choosing a\times ba×b submatrices and reduce the values in the chosen matrices by 1. If possible, print “_” in one line, or print “QAQ” in one line.
示例1
输入
2
2 2 1 2
1 2
1 2
2 3 1 2
1 2 1
1 2 1
输出
QAQ
_
题意
每次选择子矩阵a*b大小,使所有元素减一,问能不能最后矩阵中元素都为0.
思路
看到子矩阵同加一个数,立马想到二维差分,我们从左上开始依次处理,减去这个元素的差分,每次操作o(1),如果差分为负,直接退出,不会超时,朴素做法会超时,然后再遍历,看差分都是不是0。
代码
#include<bits/stdc++.h>
typedef long long ll;
const ll mod = 1e9 + 7;
namespace fastIO{
inline ll qpow(ll a,ll b){
ll ans = 1,base = a;
while(b){
if(b&1) ans = ans * base % mod;
base = base * base % mod;
b >>= 1;
}
return ans;
}
inline void input(ll &res){
char c = getchar();res = 0;int f = 1;
while (!isdigit(c)) { f ^= c == '-'; c = getchar(); }
while (isdigit(c)) { res = (res << 3) + (res << 1) + (c ^ 48);c = getchar(); }
res = f ? res : -res;
}
}
using namespace fastIO;
using namespace std;
const int N = 1e4 + 50;
ll Case,n,m,a,b;
ll x[N][N],diff[N][N];
void solve(){
bool flag = true;
input(n),input(m),input(a),input(b);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
input(x[i][j]);
diff[i][j] = x[i][j]-x[i-1][j]-x[i][j-1]+x[i-1][j-1];
}
}
for(int i=1;i+a-1<=n;i++){
for(int j=1;j+b-1<=m;j++){
ll t = -diff[i][j];
if(t>0){
flag = false;
break;
}
diff[i][j] += t;
diff[i][j+b] -= t;
diff[i+a][j] -= t;
diff[i+a][j+b] += t;
}
if(!flag) break;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(diff[i][j]){
flag = false;
break;
}
}
if(!flag) break;
}
if(flag) puts("^_^");
else puts("QAQ");
}
int main(){
Case = 1;
input(Case);
while(Case--){
solve();
}
return 0;
}