洛谷P1031 均分紙牌 寒假基礎練題(一)

2021-10-02 20:23:12 字數 1931 閱讀 1735

有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)

第二行為:(n堆紙牌,每堆紙牌初始數,1≤ai ≤10000)

一行:即所有堆均達到相等時的最少移動次數。

4

9 8 17 6

——————————————————解題分割線————————————————————

其實這道題有兩個地方是重點,乙個就是題中強調了每一堆(除了頭和尾)只可以向左堆或右堆移動紙牌,且每次移動紙牌的數量不限(這是關鍵)。還有乙個就是,題中特地強調了:紙牌總是必定是n的倍數。

那麼,很顯然,就可以求出最終每一堆的紙牌數應該是 each = total / n。

接下來就是如移動的問題,移動一定是要有秩序、有規律的移動,隨便亂移動一定不是最少的。

所以必須要找出乙個移動的起始點,而哪種堆必定是要移動的呢?

當然是初始紙牌數大於each的,而這些堆可能不止乙個,哪乙個是最適合定為起始點的呢?

那就是最多的那個紙牌堆。

找到最多的紙牌堆後,接下來就要移動紙牌了,對於乙個紙牌堆(假設紙牌堆在中間某處,在頭或尾就只要一邊討論),移動紙牌有兩個選擇:向左or向右,那麼各移動多少呢?自然可以想到,最多的那一堆所多出來紙牌數必定是他兩邊所缺的紙牌數之和,那麼就看兩邊各需要多少紙牌就各移動多少紙牌。

所以我們一開始的預處理和資料準備過程就要做到這幾個方面:1、計算出紙牌數的總和 total。2、找出紙牌數最多的那個堆,記錄下它的location。3、計算出最大紙牌數堆的左側紙牌數總和,進而求出左側需要的紙牌數(或多出的紙牌數)。

最終將移動的紙牌向兩邊分發,需要多少就給多少,多出多少就拿走多少,每出現一次這樣拿或給的情況,結果就++。

還是上**吧。

#include

using

namespace std;

int n,a[

105]

,maxx=-1

;int

main()

total +

= a[i];}

int each = total / n;

//最終實現情況

int left_need =

(each *

(loc -1)

)- left_total;

// 變數為正數即是左邊缺,為負數就是左邊富餘,缺就給,富餘就拿,同樣都需要一步來完成

int right_need = a[loc]

- left_need - each;

//右邊同理

int k = loc -1;

int ans =0;

//對左邊進行處理

while

(k >=1)

else

k--;}

k = loc+1;

//對右邊進行處理

洛谷 P1031 均分紙牌

p1031 均分紙牌 這道題告訴我們,對於實在想不出演算法的題,可以大膽按照直覺用貪心,而且在考試中永遠不要試著去證明貪心演算法,因為非常難證,會浪費大量時間。這就是你們都不去證的理由?這道題貪心演算法就是,計算牌的平均數,然後除了最後一堆以外,每堆都通過把多餘牌移到下一堆或從下一堆取牌來使其達到平...

洛谷 P1031均分紙牌

恰似又更了四章 我現在只能期待他不在什麼工作日突然來乙個十篇得大爆更了 我現在要更一篇水題了 希望不會被不小心看到的大佬們嫌棄 題目描述 有n堆紙牌,編號分別為 1,2,n。每堆上有若干張,但紙牌總數必為n的倍數。可以在任一堆上取若干張紙牌,然後移動。移牌規則為 在編號為1堆上取的紙牌,只能移到編號...

洛谷P1031 均分紙牌

題目鏈結 均分紙牌 解題思路 貪心演算法,最簡單的模擬 最壞的情況就是移動n 1次 如果紙牌本來就滿足條件就不需要再移動 預處理就是求每堆紙牌與平均數的關係,多1記為1,少1記為 1 從左至右依次掃瞄,a i 0的就把多的部分給右邊那堆,a i 0的就從右邊那堆拿過來補上 附上 include us...