一句話題意:一個數組,n
個正整數元素,每次選兩個不一樣的元素,分別一增一減,求最後最多能獲得多少個相同的元素。數組
好比,1 2 3 4 => 1 3 3 3
,就是選2 4
兩個元素分別增減的結果。這時,有三個元素相同,達到了這個例子的最大值。優化
這個題目我以爲題面有坑……我一開始讀了好幾遍都不懂。而詳細描述請參考原題。spa
原題核心描述是這樣的:.net
At any move, you choose two indices
i
andj
(0 <= i, j < N and i != j
) and increment value at one index and decrement value at other index.code
這裏的increment
和decrement
怎麼想也不該該用名詞形式吧?……仍是我孤陋寡聞了?求指教…rem
2017-02-19更新:get
increment
和decrement
在計算機科學中,有動詞用法,其義爲增/減。題目是正確的。數學
辭書來源爲weblio
:http://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
個數必定能變成徹底同樣。數學證實簡單,略去。
代碼簡單到讓人無語……這也說明了這題真的是個水題。sum
用long long
是出於數據範圍的考慮(可是事實證實,用int
仍能AC)。
有些人的代碼只用了10ms就跑完了,應是用了一些io上的優化策略。如printf
和scanf
的重寫等,之後再記。