P1031 均分紙牌——————貪心
阿新 • • 發佈:2019-01-04
P1031 均分紙牌
題目描述
有N堆紙牌,編號分別為 1,2,…,N。每堆上有若干張,但紙牌總數必為 N的倍數。可以在任一堆上取若干張紙牌,然後移動。
移牌規則為:在編號為 1堆上取的紙牌,只能移到編號為2的堆上;在編號為N的堆上取的紙牌,只能移到編號為 N−1的堆上;其他堆上取的紙牌,可以移到相鄰左邊或右邊的堆上。
現在要求找出一種移動方法,用最少的移動次數使每堆上紙牌數都一樣多。
例如N=4 4堆紙牌數分別為:
①9②8③17④6
移動3次可達到目的:
從 ③ 取4張牌放到 ④ (9,8,13,10)-> 從 ③ 取33張牌放到 ②(9,11,10,10)-> 從 ② 取1張牌放到①(10,10,10,10)。
輸入格式:
兩行
第一行為:NN(NN 堆紙牌,1 \le N \le 1001≤N≤100)
第二行為: (N堆紙牌,每堆紙牌初始數, )
輸出格式:
一行:即所有堆均達到相等時的最少移動次數。
輸入輸出樣例
輸入樣例
4
9 8 17 6
輸出樣例
3
先找出來紙牌數量的平均值ave,
然後對於每一對紙牌都讓其減去這個平均值
所以我們得到的結果就是,如果紙牌個數大於平均值,那麼它就大於0,小於平均值,它就小於0
這樣一來我們可以得出這樣的策略:從左到右開始找,如果第i堆紙牌的個數 不等於0,那麼移動次數就+1, ,一直處理到最後一個就行,應為題目保證紙牌總數必為N的倍數,所以不用擔心陣列越界
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,ave;
int a[108];
cin>>n;
for(int i=0;i<n;++i)
cin>>a[i], ave+=a[i];
ave/=n;
for(int i=0;i<n;++i) a[i]-=ave;
int ans = 0;
for(int i=0;i<n;++i)
{
if(!a[i]) continue;
a[i+1]+=a[i];
ans++;
}
cout<<ans<<endl;
return 0;
}