SPOJ - MKEQUAL

SPOJ - MKEQUAL - Make them equal !

https://vjudge.net/problem/SP...web

一句话题意:一个数组,n个正整数元素,每次选两个不一样的元素,分别一增一减,求最后最多能获得多少个相同的元素。数组

好比,1 2 3 4 => 1 3 3 3,就是选2 4两个元素分别增减的结果。这时,有三个元素相同,达到了这个例子的最大值。优化

这个题目我以为题面有坑……我一开始读了好几遍都不懂。而详细描述请参考原题。spa

原题核心描述是这样的:.net

At any move, you choose two indices i and j ( 0 <= i, j < N and i != j ) and increment value at one index and decrement value at other index.code

这里的incrementdecrement怎么想也不该该用名词形式吧?……仍是我孤陋寡闻了?求指教…rem

2017-02-19更新:get

incrementdecrement在计算机科学中,有动词用法,其义为增/减。题目是正确的。数学

辞书来源为webliohttp://ejje.weblio.jp/content...io


解:一增一减以后,数组元素总和不会变。因此,一个数组的元素达到多少个相同,应与元素总和有关!

再进一步思考,要想相同的元素最多,其实就是想把这个元素总和“更平均地分给全部的元素”。这就要求咱们尽可能让每一个数都经过一增一减的操做逼近元素的平均值。

因此,就有了下面的代码。

//AC,30ms
#include<cstdio>
#define LL long long
using namespace std;
int main(){
    int t,n,temp;
    scanf("%d", &t);
    while(t--){
        LL sum = 0;
        scanf("%d", &n);
        for(int i = 0;i < n;i++){
            scanf("%d", &temp);
            sum+=temp;
        }
        printf("%d\n", n-(sum%n?1:0));
    }
    return 0;
}

其核心思想是尽可能平摊元素总和。若没法彻底平摊,则把没法平摊的那部分,转嫁给其中的一个元素。

代码直接利用了此结论:若元素总和能被n整除,则必定能分摊,结果是n。若没法整除,剩下的n-1个数必定能变成彻底同样。数学证实简单,略去。

代码简单到让人无语……这也说明了这题真的是个水题。sumlong long是出于数据范围的考虑(可是事实证实,用int仍能AC)。

有些人的代码只用了10ms就跑完了,应是用了一些io上的优化策略。如printfscanf的重写等,之后再记。

相关文章
相关标签/搜索