给你一个大小为 m x n 的二维整数网格 grid 和一个整数 x 。每一次操作,你可以对 grid 中的任一元素 加 x 或 减 x 。
单值网格 是全部元素都相等的网格。
返回使网格化为单值网格所需的 最小 操作数。如果不能,返回 -1 。
示例 1:

输入:grid = [[2,4],[6,8]], x = 2
输出:4
解释:可以执行下述操作使所有元素都等于 4 :
- 2 加 x 一次。
- 6 减 x 一次。
- 8 减 x 两次。
共计 4 次操作。
示例 2:

输入:grid = [[1,5],[2,3]], x = 1
输出:5
解释:可以使所有元素都等于 3 。
示例 3:

输入:grid = [[1,2],[3,4]], x = 2
输出:-1
解释:无法使所有元素相等。
提示:
m == grid.lengthn == grid[i].length1 <= m, n <= 10^51 <= m * n <= 10^51 <= x, grid[i][j] <= 10^4
分析:所有元素只能加减 x,因此任意两个元素之差必须是 x 的倍数,否则无法使它们相等。遍历网格,将所有元素取出放入一维数组 num,同时检查 (gridij−grid00)%x 是否等于 0。如果存在不满足的元素,直接返回 −1。
接下来先将 nums 排序。由于每次操作改变量为 x,将元素 numsi 变为目标值 t 的操作次数为
∣numsi−t∣/x,因此问题等价于最小化对所有 i 求操作次数之和。根据中位数的性质,当 t 取排序后数组的中位数时,绝对值之和最小。
cpp
int cmp(const void *a,const void *b)
{
return *(int*)a-*(int*)b;
}
int minOperations(int** grid, int gridSize, int* gridColSize, int x) {
int m=gridSize,n=*gridColSize,base=grid[0][0],ans=0,t=0;
int num[m*n+5];
for(int i=0;i<m;++i)
{
for(int j=0;j<n;++j)
{
if((grid[i][j]-base)%x!=0)return -1;
num[t++]=grid[i][j];
}
}
qsort(num,t,sizeof(int),cmp);
int val=num[t/2];
for(int i=0;i<t;++i)
ans+=abs(val-num[i])/x;
return ans;
}