2020小米选拔赛D 二维差分套前缀和 Matrix Subtraction

原题:https://ac.nowcoder.com/acm/contest/7501/J

大致题意:给你一个n x m的矩阵,我们可以对其中任意一个a x b的矩阵进行操作(所有元素减一)。可以进行无限次操作,每次可以选任意一个a x b的矩阵。 求问是否可以让n x m的矩阵内的所有元素为零

 

思路:

对于nxm的矩阵,从左上角第一个元素in[1][1]开始,如果要让nxm的矩阵所有元素为零,那么在in[1][1]上必须进行in[1][1]次操作,而对in[1][1]可进行操作的axb的矩阵是唯一的。

处理完in[1][1]后,我们需要记录从1 1 到a b这个矩阵内已经减掉了in[1][1]这个事实。所以我们可以用一个二维数据deduct[i][j]来记录当前ij点上的在之前的操作中删去的个数。

deduct在遍历的过程中转化为前缀和。而当在ab范围内减去一个数字的时候进行差分。

 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 typedef long long ll;
 5 const int mx=1e3+10;
 6 ll deduct[mx][mx], in[mx][mx];
 7 int main(){
 8     ll T, n, m, a, b;
 9     scanf("%lld", &T);
10     for(ll lp=1;lp<=T;lp++){
11         scanf("%lld %lld %lld %lld", &n, &m, &a, &b);
12         for(ll i=1;i<=n;i++) {
13             for (ll j = 1; j <= m; j++)
14                 scanf("%lld", &in[i][j]);
15         }
16         memset(deduct, 0, sizeof(deduct));
17         bool ok=true;
18         for(ll i=1;i<=n&&ok;i++){
19             for(ll j=1;j<=m&&ok;j++){
20                 deduct[i][j]+=deduct[i-1][j]+deduct[i][j-1]-deduct[i-1][j-1];
21                 //求前缀和
22                 if(deduct[i][j]>in[i][j]){//如果已经减去的数量比当前的数值大了 不可能为0
23                     ok=false;
24                     break;
25                 }
26                 else if(deduct[i][j]<in[i][j]){//如果比当前的数量小 意味着还要继续减
27                     ll t=in[i][j]-deduct[i][j];
28                     if(i+a-1>n||j+b-1>m){
29                         ok=false;
30                         break;
31                     }
32                     //差分
33                     //当前的减了 axb范围内的数据都要减
34                     deduct[i][j]+=t, deduct[i+a][j+b]+=t;
35                     deduct[i+a][j]-=t, deduct[i][j+b]-=t;
36                 }
37             }
38         }
39         printf("%s\n", ok?"^_^":"QAQ");
40     }
41     return 0;
42 }

 

2020小米选拔赛D 二维差分套前缀和 Matrix Subtraction

上一篇:Hypergraph Neural Networks超图神经网络


下一篇:Oracle导入导出 备份迁移Imp Exp