H题题解:
题目解析:
给定一个 n行m列 的矩阵,先计算每个位置的周边和(包含自身 + 周围特定范围的元素和);找到初始时周边和最大的位置; 进行 q 次更新操作:每次给矩阵中某个位置加上数值 z,并同步更新受影响位置的周边和,每次操作后输出当前周边和最大的位置(坐标还原为原始矩阵的坐标)
代码演示:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 500010;
// 全局数组:arr存原始矩阵值,brr存每个位置的周边和
int arr[505][505], brr[505][505];
void solve(){ // 核心逻辑函数
int n,m,q,x,y,z;
cin>>n>>m>>q; // 输入:矩阵行数n、列数m、操作次数q
// 1. 读取原始矩阵(注意:矩阵从下标2开始存,避免越界)
for(int i=2;i<=n+1;i++){
for(int j=2;j<=m+1;j++){
cin>>arr[i][j]; // 原始矩阵的(i-1,j-1)对应这里的(i,j)
}
}
// 2. 计算每个位置的初始「周边和」
for(int i=2;i<=n+1;i++){
for(int j=2;j<=m+1;j++){
// 核心:brr[i][j] = 自身 + 周围特定位置的arr值之和
brr[i][j] = arr[i][j-2] + arr[i][j-1] + arr[i][j+1] + arr[i][j+2] + arr[i-1][j-1] + arr[i-1][j] + arr[i-1][j+1] + arr[i-2][j] + arr[i+2][j] + arr[i+1][j-1] + arr[i+1][j] + arr[i+1][j+1] + arr[i][j];
}
}
// 3. 找初始「周边和」最大的位置
int mx=0; // 记录最大的周边和
pair<int,int>pi; // 记录最大和对应的坐标(pair是存一对数的容器)
for(int i=2;i<=n+1;i++){
for(int j=2;j<=m+1;j++){
if(brr[i][j]>mx){ // 找到更大的和
mx=brr[i][j]; // 更新最大值
pi.first=i; // 记录行坐标
pi.second=j; // 记录列坐标
}
}
}
// 4. 处理q次更新操作
while(q--){
cin>>x>>y>>z; // 输入:要更新的原始坐标(x,y),要加的数值z
x++; // 转换为数组的存储坐标(因为数组从2开始,原始x=0对应数组x=1?不,这里是原始x+1→数组x+1,最终数组下标是2开始)
y++; // 比如原始坐标(0,0) → 数组坐标(1,1)?实际是为了和前面的存储逻辑对齐
// 遍历当前更新位置周围±2格的范围(只处理「周边和」受影响的位置)
for(int i=-2;i<=2;i++){
for(int j=-2;j<=m+1;j++){ // 原代码笔误?应该是j<=-2;j<=2
// 过滤:只处理「曼哈顿距离≤2」的位置(即横向+纵向偏移和≤2)
if(abs(i)+abs(j)>2) continue;
// 计算受影响的位置坐标
int nx=x+i;
int ny=y+j;
// 边界判断:确保坐标在有效范围内(数组从2开始,到n+1/m+1结束)
if(nx>=2&&nx<=n+1&&ny>=2&&ny<=m+1){
brr[nx][ny]+=z; // 更新该位置的周边和(因为原始位置加了z,周边和同步加z)
// 如果更新后这个位置的和更大,更新最大值和坐标
if(brr[nx][ny]>mx){
mx=brr[nx][ny];
pi.first=nx;
pi.second=ny;
}
}
}
}
// 输出:还原为原始矩阵的坐标(数组坐标-1)
cout<<pi.first-1<<" "<<pi.second-1<<endl;
}
}
signed main(){
ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
int T=1;//cin>>T;
while(T--){
solve();
}
return 0;
}

京公网安备 11010502036488号