C++ 代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#include <climits>
#include <vector>
typedef long long LL;
const int N = 100;
int t;
int a[N][N];
int main()
{
scanf("%d", &t);
while (t -- )
{
int n, m;
LL res = 0;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
for (int j = 1; j<=m; j++)
scanf("%d", &a[i][j]);
for (int i = 1; i<=(n+1)/2; i++)
for (int j = 1; j<= (m+1)/2; j++)
{
vector<int> v;
int a1 = a[i][j];
int a2 = a[i][m-j+1];
int a3 = a[n-i+1][j];
int a4 = a[n-i+1][m-j+1];
v.push_back(a1);
v.push_back(a2);
v.push_back(a3);
v.push_back(a4);
sort(v.begin(), v.end());
LL cur = abs(a1-v[1])+abs(a2-v[1])+abs(a3-v[1])+abs(a4-v[1]);
if (i==n-i+1 || j == m-j+1) cur = cur/2;
res += cur;
}
cout<<res<<endl;
memset(a, 0, sizeof a);
}
}
定位四个点后,找到中位数来计算出差值和。如果行和列都为奇数,那最后定位出四个数字都是相等的,差值和一定为0;所以只需要判断行或列为奇数,因为相当于有两个点重复加了两次,差值和除以2就可以了。