题面
小企鹅polo有一个由整数组成的n*m矩阵,他每次让矩阵中的某个元素增加或减少d,求最小操作次数使得矩阵中的所有元素相同,如果不能输出-1.小企鹅polo有一个由整数组成的n*m矩阵,他每次让矩阵中的某个元素增加或减少d,求最小操作次数使得矩阵中的所有元素相同,如果不能输出-1.
本题启用子任务评分。
对于一个子任务,当且仅当你通过了该子任务的所有测试点,你才能得到该子任务的分数。
Subtask1(9分):1 ≤ n, m ≤ 2, 1 ≤ d ≤ 2,1 ≤ aij ≤ 2
Subtask2(14分):1 ≤ n, m ≤ 20, 1 ≤ d ≤ 2,1 ≤ aij ≤ 2
Subtask3(26分):1 ≤ n, m ≤ 20, 1 ≤ d ≤ 100,1 ≤ aij ≤ 100
Subtask4(51分):1 ≤ n, m ≤ 100, 1 ≤ d ≤ 10^4,1 ≤ aij ≤ 10^4
分析
很简单的一个贪心,排序,判断一下两数之间是否满足d的整数倍差值,如果可以被修改,显然是中位数最近。
坑点在于捆绑测试,要小心。有几个比较衰的因为一组特殊数据从期望得分100直接变0分了
代码
#include<bits/stdc++.h> using namespace std; #define N 100010 int n,m,d,cnt; long long ans; int a[N]; inline void read(int &x) { x=0;char ch=getchar(); while(ch>'9'||ch<'0'){ch=getchar();} while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();} } int main() { read(n);read(m);read(d); cnt=n*m; for(int i=1;i<=cnt;i++) read(a[i]); sort(a+1,a+1+cnt); int mid=1+cnt>>1; for(int i=1;i<mid;i++) if((a[i+1]-a[i])%d==0) ans+=(long long)i*(a[i+1]-a[i])/d; else { printf("-1 "); return 0; } for(int i=mid+1;i<=cnt;i++) if((a[i]-a[i-1])%d==0) ans+=(long long)(cnt-i+1)*(a[i]-a[i-1])/d; else { printf("-1 "); return 0; } printf("%lld ",ans); return 0; }