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的重寫等,之後再記。

相關文章
相關標籤/搜索