B. Nice Matrix
题意:给出一个矩阵,让你做变换(给任一元素加减1)使得矩阵任一行列均为回文,求出最少的变换次数.
因为数据很小,而且我们发现,枚举一个点,需要把他对应的四个角都要求出来,所以我们直接暴力枚举左上四分之一部分就可以了,但是要注意,如有奇数行或者列出现的时候,枚举的时候要加上,并进行特判
借一个图
图片地址
中间红色就是特判区域
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <string>
#include <cmath>
#include <cstdlib>
#include <stack>
using namespace std;
typedef long long ll;
const int maxn = 100 + 5;
const int Size = 20;
int matrix[maxn][maxn];
int main()
{
std::ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--){
int n,m;//行列
cin>>n>>m;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
cin>>matrix[i][j];
}
}
int x[5];// 存四个角的位置
ll ans = 0;
//如果行列有奇数,也要把奇数的行列算进去
int midr = n / 2 + n % 2, midc = m / 2 +m % 2;
for(int i = 1; i <= midr; i++){
for(int j = 1; j <= midc; j++){
x[1] = matrix[i][j];//左上
x[2] = matrix[i][m - j + 1];//右上
x[3] = matrix[n - i + 1][j];//左下
x[4] = matrix[n - i + 1][m - j + 1];//右下
//如果行列都为奇数,那么中间的那一部分一定不需要更改
if(i == n - i + 1&&j == m - j + 1) continue;
//如果是行为奇数,列为偶数,即左上左下重合,右上右下重合
else if(i == n - i + 1) ans += abs(x[1] - x[2]);
//如果是列为奇数,行为偶数,即左上右上重合,左下右下重合
else if(j == m - j + 1) ans += abs(x[1] - x[3]);
else{
sort(x + 1, x + 4 + 1);
int mid = (x[2] + x[3]) >>1;
ans += x[4] - x[1] + x[3] - x[2];//其实这样就可以,因为肯定要在中间找,那么不管找哪个位置
//都是这四个数两两做差
//for(int k = 1; k <= 4; k++) ans += abs(x[k] - mid);
}
}
}
cout<<ans<<endl;
}
return 0;
}