題目鏈結
題目描述
有n堆紙牌,編號分別為 1,2,…,n。每堆上有若干張,但紙牌總數必為n的倍數。可以在任一堆上取若干張紙牌,然後移動。
移牌規則為:在編號為1堆上取的紙牌,只能移到編號為2的堆上;在編號為n的堆上取的紙牌,只能移到編號為n−1的堆上;其他堆上取的紙牌,可以移到相鄰左邊或右邊的堆上。
現在要求找出一種移動方法,用最少的移動次數使每堆上紙牌數都一樣多。
例如n=4,4堆紙牌數分別為:
①9②8③17④6
移動3次可達到目的:
從 ③ 取4張牌放到 ④ (9,8,13,10)-> 從 ③ 取3張牌放到 ②(9,11,10,10)-> 從 ② 取1張牌放到①(10,10,10,10)。
輸入兩行
第一行為:n(n 堆紙牌,1≤n≤100)
第二行為:a1,a2,…,an (n堆紙牌,每堆紙牌初始數,1≤ai≤10000)
輸出
一行:即所有堆均達到相等時的最少移動次數。
輸入樣例
4
9 8 17 6
輸出樣例
3
分析
這是乙個比較典型的貪心
首先我們求出目標狀態每堆牌的數量s,然後用s更新每堆牌。如樣例,s = 10,更新後為-1,-2,7,-4。
然後,我們用乙個很巧妙的思路,我們可以認為第一堆上有-1張牌,第二堆上有-2張牌,一次類推。每次我們把當前位置上的牌數移動到下乙個位置,直到某個位置牌數為0。
也就是說,用乙個陣列 q[110] 存下更新後的序列,每次進行q[ i + 1] += q[ i ]; q[ i ] = 0;的操作。
這裡還可以加上乙個小優化,針對特殊情況開始或者結尾有很多個0,我們把頭指標指向序列中第乙個不為0的數,尾指標指向序列中最後乙個不為0的數。這樣做可能對絕大多數情況起不了什麼結果,但對於特殊情況就可以提速不少。
就是這樣。
**
#includeusing namespace std;
int a[107];
int s, ans;
int main()
s /= n;
for (int i = 1; i <= n; i++)
int i = 1, j = n;
while (a[i] == 0 && i < n) i++;
while (a[j] == 0 && j > 1) j--;
while (i < j)
cout << ans;
return 0;
}
貪心 均分紙牌
時間限制 1 sec 記憶體限制 64 mb 提交 164 解決 95 提交 狀態 討論版 有n堆紙牌,編號分別為1,2,n。每堆上有若干張,但紙牌總數必為n的倍數。可以在任一堆上取若干張紙牌,然後移動。移牌規則為 在編號為1堆上取的紙牌,只能移到編號為2的堆上 在編號為n的堆上取的紙牌,只能移到編...
均分紙牌(貪心)
有n堆紙牌,編號分別為1,2,n。每堆上有若干張,但紙牌總數必為n的倍數。可以在任一堆上取若干張紙牌,然後移動。移牌規則為 在編號為1的堆上取的紙牌,只能移到編號為2的堆上 在編號為n的堆上取的紙牌,只能移到編號為n 1的堆上 其他堆上取的紙牌,可以移到相鄰左邊或右邊的堆上。現在要求找出一種移動方法...
codevs均分紙牌 貪心演算法
題目描述 description 有 n 堆紙牌,編號分別為 1,2,n。每堆上有若干張,但紙牌總數必為 n 的倍數。可以在任一堆上取若於張紙牌,然後移動。移牌規則為 在編號為 1 堆上取的紙牌,只能移到編號為 2 的堆上 在編號為 n 的堆上取的紙牌,只能移到編號為 n 1 的堆上 其他堆上取的紙...