【NOIP模拟】企鹅矩阵

题面

小企鹅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\n");
            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\n");
            return 0;
        }                                                                       
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/NSD-email0820/p/9653266.html