題目連接:https://www.luogu.org/problemnew/show/P1031c++
題目描述
有 $N$ 堆紙牌,編號分別爲 $1,2,…,N$。每堆上有若干張,但紙牌總數必爲 $N$ 的倍數。能夠在任一堆上取若干張紙牌,而後移動。spa
移牌規則爲:在編號爲 $1$ 堆上取的紙牌,只能移到編號爲 $2$ 的堆上;在編號爲 $N$ 的堆上取的紙牌,只能移到編號爲 $N-1$ 的堆上;其餘堆上取的紙牌,能夠移到相鄰左邊或右邊的堆上。code
如今要求找出一種移動方法,用最少的移動次數使每堆上紙牌數都同樣多。blog
例如 $N=4$,$4$堆紙牌數分別爲:ci
①$9$ ②$8$ ③$17$ ④$6$
移動 $3$ 次可達到目的:get
從 ③ 取 $4$ 張牌放到 ④ $(9,8,13,10)$ -> 從 ③ 取 $3$ 張牌放到 ② $(9,11,10,10)$ -> 從 ② 取 $1$ 張牌放到① $(10,10,10,10)$。it
輸入輸出格式
輸入格式:
兩行class
第一行爲:$N$($N$ 堆紙牌,$1 \le N \le 100$)方法
第二行爲:$A_1,A_2, … ,A_n$($N$堆紙牌,每堆紙牌初始數,$1 \le A_i \le 10000$)移動
輸出格式:
一行:即全部堆均達到相等時的最少移動次數。
輸入輸出樣例
輸入樣例#1:
4
9 8 17 6
輸出樣例#1:
3
題解:
首先,因爲總牌數是 $N$ 的整數倍,所以確定是能夠有解的。每一個牌堆最終的牌數就是總牌數除以堆數,設爲 $k$。
其次,任意相鄰的兩個牌堆之間,最多隻進行一次移牌操做,不然就是多餘操做(這是很顯然的)。所以,無論怎麼樣,移動次數最多也就 $N-1$ 次。
那麼,如何判斷這個間隔是否須要進行移牌操做?
其實很簡單,假設這個間隔是牌堆 $i$ 和 牌堆 $i+1$ 的間隔,那麼只要前 $i$ 堆牌數之和不等於 $k \cdot i$,就要在牌堆 $i$ 和牌堆 $i+1$ 之間進行一次移牌操做。
緣由也很簡單,左邊的牌數不對,右邊的牌數天然也不對,若是不在當前這個間隔移牌,就不可能讓左右兩邊的牌數變對,所以必須移牌。
AC代碼:
#include<bits/stdc++.h> using namespace std; int n,k,s[105]; int main() { cin>>n; for(int i=1,x;i<=n;i++) cin>>x, s[i]=s[i-1]+x; k=s[n]/n; int ans=0; for(int i=1;i<=n;i++) if(s[i]!=k*i) ans++; cout<<ans<<endl; }