2020ICPC·小米网络选拔赛第一场 J.Matrix Subtraction
题目链接:点击这里
题意:有一个
n
×
m
n×m
n×m 的矩阵
M
M
M,通过反复选择子矩阵
a
×
b
a \times b
a×b 并且使子矩阵中的所有元素都减去
1
1
1,问最终矩阵
M
M
M 能否变为全
0
0
0。如果可能,在一行中打印 ^_^
,否则在一行中打印 QAQ
。
思路:从左上角开始,一行一行地减去当前值使之变为
0
0
0,利用二维差分可以快速实现这个操作。如果中途出现了负数或最后不全为
0
0
0,则输出 QAQ
。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1010;
int n, m, a, b;
int f[N][N];
// 给以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵中的所有元素加上c
void add(int x1, int y1, int x2, int y2, int c)
{
f[x1][y1] += c;
f[x2 + 1][y1] -= c;
f[x1][y2 + 1] -= c;
f[x2 + 1][y2 + 1] += c;
}
bool judge()
{
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
if(f[i][j] != 0)
return false;
return true;
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
memset(f, 0, sizeof f);
scanf("%d%d%d%d", &n, &m, &a, &b);
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
int x;
scanf("%d", &x);
add(i, j, i, j, x);
}
}
bool success = true;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
f[i][j] += f[i - 1][j] + f[i][j - 1] - f[i - 1][j - 1];
if(f[i][j] < 0)
{
success = false;
break;
}
int ii = i + a - 1, jj = j + b - 1;
if(ii <= n && jj <= m)
{
add(i, j, ii, jj, -f[i][j]);
}
}
if(!success) break;
}
if(!success)
{
puts("QAQ");
continue;
}
if(judge()) puts("^_^");
else puts("QAQ");
}
return 0;
}
微信公众号《算法竞赛求职》,致力于详细讲解竞赛和求职所涉及到的算法原理和模板。欢迎关注,一起交流进步!
本文地址:https://blog.csdn.net/qq_42815188/article/details/109296954
上一篇: 一般玉米要煮多久才熟?吃玉米对于身体都有什么好处?
下一篇: java i++和 ++i
推荐阅读
-
2020ICPC·小米 网络选拔赛热身赛-A.ABBA
-
2020ICPC·小米网络选拔赛第一场 J.Matrix Subtraction
-
2020ICPC·小米 网络选拔赛第一场 D - Router Mesh(求删掉割点后的连通块数)
-
2020ICPC·小米 网络选拔赛第一场 A Intelligent Warehouse
-
2020ICPC·小米 网络选拔赛热身赛
-
2020ICPC·小米 网络选拔赛第一场 题解
-
2020ICPC·小米网络选拔赛第一场 J.Matrix Subtraction
-
2020ICPC·小米 网络选拔赛热身赛-A.ABBA
-
2020ICPC·小米 网络选拔赛第一场 A Intelligent Warehouse
-
2020ICPC·小米 网络选拔赛第一场 D - Router Mesh(求删掉割点后的连通块数)