題意:對於n堆石子,每堆若干個,兩人輪流操作,每次操作分兩步,第一步從某堆中去掉至少乙個,第二步(可省略)把該堆剩餘石子的一部分分給其它的某些堆。最後誰無子可取即輸。(參考清晰明白)
思路:首先我們考慮兩堆相等的情況,一定是誰取誰輸,因為對方永遠可以做對稱的操作。對於四堆,1、2堆相等,3、4堆相等的情況,一定也是先手輸,後手也只需要做對稱的操作(在先手取石子的對稱堆中取相同多的石子,並把和先手等量的石子分給先手分配給的堆的對稱堆。(若先手在3堆取,並分給1堆,那後手就在4堆取,分給2堆)。也就是說對於任意的一對一對相等的情況來說,一定是後手必勝。
我們接下來來證明除上述情況外,所有情況都是先手必勝。因為任何一種情況都可以轉化為一對一對相等的情況。若總堆數為奇數的情況,可以把石子最多的一堆的石子分配給其它堆,使得其它堆兩兩相等。最多一堆的石子絕對是足夠多,可以完成這個補齊的任務的。因為我們把石子從小到大排序後畫成條形統計圖(
這個想法太巧妙了!!)。把相鄰兩個分成一組(1和2一組,3和4一組……)我們需要用第n堆填補1,3,5……堆我們把需要填補的這些差距(2比1高出的部分,4比3高出的部分……)投影到統計圖左側的y軸上,我們會發現這是一些不連續的區間,其長度總和明顯小於第n堆。所以可以補齊。
對於堆數為偶數的情況。我們把最多的一堆削弱到和最少的一堆一樣多,並把拿掉的石子分給別的堆,使其一對一對地相等。可行性於前面奇數情況同理。
所以只要判斷是不是一對一對的相等的情況即可。
#include #include int s[15],n;
int cmp(const void *a,const void *b)
int main(){
while(scanf("%d",&n) &&n){
int i,flag = 1;
for(i = 0;i
poj1740 博弈論,對稱博弈)
題目 有若干堆石子,每一次需要從一堆石子中拿走一些,然後如果願意的話,再從這堆石子中拿一些分給其它任意堆。不能操作的人負。解析 實際上如果n為偶數,我們就可以把ta們兩兩配對 轉換成只有兩堆石子的情況 按照石子數從小到大排序,兩兩配對成一組,組與組之間互不影響 如果可以完美配對 配對後每一組都有兩堆...
乙個遊戲框架
最近一段時間不是很忙,就寫了乙個自己的遊戲伺服器框架雛形,很多地方還不夠完善,但是基本上也算是能夠跑起來了。我先從上層結構說起,一直到實現細節吧,想起什麼就寫什麼。第一部分 伺服器邏輯 伺服器這邊簡單的分為三個部分,客戶端的連線首先到達閘道器伺服器,閘道器這裡有個執行緒用來監聽來自與客戶端的連線,然...
乙個遊戲社交產品
那是不是可以讓我的社交網路只顯示我想看到的內容?或許演算法可以強大到那個地步,但是這種被機器支配的生活,畢竟不是大家所期望的。google 引入了圈子,把朋友家人分組後,可以針對不同的圈子分享不同的事情,但是,太複雜了不是嗎?至少我身邊的人基本都不會去把所有的人分組,然後向不同的組發不同的狀態。貌似...