均分紙牌 題目鏈結
這道題是一道貪心問題(也有不用貪心方法寫的)。
解題思路:
顯然我們要先求和,把牌堆的平均值求出。
題目上說,每次只能向左右兩邊移動一次(第一堆,最後一堆除外),最少要多少次。
我們不如從一組例項來講吧:
上述十個數字,平均值為10.
我們,這樣看:
第乙個數字等於10,忽略。
第二個數字小於10。第三個數字小於10。恰好第四個大於10。第四個或許能給第
二、第三個牌堆分一些牌。但是只能讓其中乙個達到平均值。所以,我們不慌,繼續往後看,第五個數字是21,多出來許多牌,他能給第
二、第三堆牌一些。
那我們要從第四堆中拿出四張,第五堆拿出一張來,給第二第三堆。為了保證步數少。我們從第五堆拿出一張放入第四,第四拿出五張放入第三。第三拿出三張,放入第二。第二第三第四就都達到了平均值。
然後從第五堆往後看,第五堆多出了十張,然而前面都達到了平均值,這多出來的牌,只能往後面放。
我們從第五堆拿出十張放入第六堆,第六拿出1張,放入第七堆。第七堆拿出3張,放入第八堆。第八堆拿出1張,放入第九堆。
第十堆,等於10,忽略。
下面是我的實現**。
/*
name: p1031 均分紙牌
author: justno
date: 15/11/18 19:44
description:
用時: 13ms / 記憶體: 780kb
*/#include #include using namespace std;
int main()
w=c/n;//平均值
more=less=0;
/* more:當前大於w的牌堆多出來的牌數
less:當前小於w的牌堆缺的牌數
*/ k=1000;
for (int i=1;i<=n;i++)
if (more>=less&&more!=0&&less!=0)
else
}
} printf ("%d\n",s);
return 0;
}
下面是相同思想的更簡單的實現方法:
#include #include using namespace std;
int main()
; scanf ("%d",&n);
for (int i=1;i<=n;i++)
w=c/n;
for (int i=1;i<=n;i++)
a[i]-=w;
for (int i=1;i<=n;i++) }
printf ("%d\n",s);
return 0;
}
這是這個作者的:
他是第乙個題解。
洛谷 P1031 均分紙牌(貪心)
有 n 堆紙牌,編號分別為 1,2,n。每堆上有若干張,但紙牌總數必為 n 的倍數。可以在任一堆上取若干張紙牌,然後移動。移牌規則為 在編號為 1 堆上取的紙牌,只能移到編號為 2 的堆上 在編號為 n 的堆上取的紙牌,只能移到編號為 n 1 的堆上 其他堆上取的紙牌,可以移到相鄰左邊或右邊的堆上。...
洛谷 P1031 均分紙牌
p1031 均分紙牌 這道題告訴我們,對於實在想不出演算法的題,可以大膽按照直覺用貪心,而且在考試中永遠不要試著去證明貪心演算法,因為非常難證,會浪費大量時間。這就是你們都不去證的理由?這道題貪心演算法就是,計算牌的平均數,然後除了最後一堆以外,每堆都通過把多餘牌移到下一堆或從下一堆取牌來使其達到平...
洛谷 P1031均分紙牌
恰似又更了四章 我現在只能期待他不在什麼工作日突然來乙個十篇得大爆更了 我現在要更一篇水題了 希望不會被不小心看到的大佬們嫌棄 題目描述 有n堆紙牌,編號分別為 1,2,n。每堆上有若干張,但紙牌總數必為n的倍數。可以在任一堆上取若干張紙牌,然後移動。移牌規則為 在編號為1堆上取的紙牌,只能移到編號...