练习cf2033B. Sakurako and Water
题目如下
B. Sakurako and Water
time limit per test2 seconds
memory limit per test256 megabytes
During her journey with Kosuke, Sakurako and Kosuke found a valley that can be represented as a matrix of size 𝑛×𝑛, where at the intersection of the 𝑖-th row and the 𝑗-th column is a mountain with a height of 𝑎𝑖,𝑗. If 𝑎𝑖,𝑗<0, then there is a lake there.
Kosuke is very afraid of water, so Sakurako needs to help him:
With her magic, she can select a square area of mountains and increase the height of each mountain on the main diagonal of that area by exactly one.
More formally, she can choose a submatrix with the upper left corner located at (𝑖,𝑗) and the lower right corner at (𝑝,𝑞), such that 𝑝−𝑖=𝑞−𝑗. She can then add one to each element at the intersection of the (𝑖+𝑘)-th row and the (𝑗+𝑘)-th column, for all 𝑘 such that 0≤𝑘≤𝑝−𝑖.
Determine the minimum number of times Sakurako must use her magic so that there are no lakes.
Input
The first line contains a single integer 𝑡 (1≤𝑡≤200) — the number of test cases.
Each test case is described as follows:
The first line of each test case consists of a single number 𝑛 (1≤𝑛≤500).
Each of the following 𝑛 lines consists of 𝑛 integers separated by spaces, which correspond to the heights of the mountains in the valley 𝑎 (−105≤𝑎𝑖,𝑗≤105).
It is guaranteed that the sum of 𝑛 across all test cases does not exceed 1000.
Output
For each test case, output the minimum number of times Sakurako will have to use her magic so that all lakes disappear.
题目大意
有一个n*n的矩阵,现在需要使每个坐标上小于0的数都大于等于0,现在有这样的魔法,每次可以使所有左顶点为(i,j)右下顶点为(p,q)且满足𝑝−𝑖=𝑞−𝑗的子矩阵的主对角线上的所有点加一,直到填完所有小于0的坐标点。请问需要多少次操作。
题目分析
注意是主对角线,是从左上到右下的对角线。这样的对角线一共有2*n-1条。
那么,先初始化这样一个数组用于存储每条主对角线中最小的数,因为每次填对角线都是一整条线一起填,那么优先考虑最小的数。
点击查看代码
for(int i = 0; i < 2 * n; i++){
min_diag[i] = 0;
}
点击查看代码
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
int d = i - j + n;
if(a[i][j] < min_diag[d]){
min_diag[d] = a[i][j];
}
}
}
点击查看代码
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
int t;
cin >> t;
while(t--){
int n;
cin >> n;
int a[505][505];
int min_diag[2000];
for(int i = 0; i < 2 * n; i++){
min_diag[i] = 0;
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
cin >> a[i][j];
}
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
int d = i - j + n;
if(a[i][j] < min_diag[d]){
min_diag[d] = a[i][j];
}
}
}
int ans = 0;
for(int d = 1; d <= 2 * n - 1; d++){
ans += abs(min_diag[d]);
}
cout << ans << endl;
}
return 0;
}

浙公网安备 33010602011771号