1063: A Funny Game 博弈问题

1063: A Funny Game


ResultTIME LimitMEMORY LimitRun TimesAC TimesJUDGE
3s8192K627219Standard

1st JOJ Cup Online VContest Warmup Problem

Tom and Jack are on the train. The journey is too dull so much so that both of them are eager to find a way to fritter away the time. Tom is a student of mathematics department. He proposes a funny game to play with Jack. First pile up N chips where 1<N<100000, then Jack takes away at most P=N-1 chips from the pile. After that, Tom takes away at most(or equals) Q=2*P chips from the pile. Then it turns to Jack again, he takes away at most(or equals) P=2*Q. Each time both of them have to take away at least 1 chip. In the same way, the process continues and who takes away the last chip wins the game. Jack knows there must be something tricky in the game, so he's decided to write a program to check whether there exists a win-strategy(no matter how many chips Tom takes away each time, Jack will win) for himself for a specific N. You know Jack is very good at programming, so solving this problem doesn't take him too much time. Do you know how he does?

Input Specification

The input consists of several lines, each of which consists of an integer N. The last line of the input is 0, which you shouldn't process.

Output Specification

For each N, you should output either YES or NO. If there exists a win-strategy for Jack, output YES. Otherwise output NO.

Sample Input

2
3
4
5
1000
0

Sample Output

NO
NO
YES
NO
YES
这个题目是一类题目的典型,都是数学.
下面是解释:
火柴遊戲,亦可用牙籤來代替火柴玩遊戲。 
一個最普通的火柴遊戲就是兩人一起玩,先置若干支火柴於桌上,兩人輪流取,每次所取
的數目可先作一些限制,規定取走最後一根火柴者獲勝。 
規則一:若限制每次所取的火柴數目最少一根,最多三根,則如何玩才可致勝? 
例如:桌面上有n=15根火柴,甲﹑乙兩人輪流取,甲先取,則甲應如何取才能致勝? 
為了要取得最後一根,甲必須最後留下零根火柴給乙,故在最後一步之前的輪取中,甲不
能留下1根或2根或3根,否則乙就可以全部取走而獲勝。如果留下4根,則乙不能全取,則
不管乙取幾根(1或2或3),甲必能取得所有剩下的火柴而贏了遊戲。同理,若桌上留有8
根火柴讓乙去取,則無論乙如何取,甲都可使這一次輪取後留下4根火柴,最後也一定是甲
獲勝。由上之分析可知,甲只要使得桌面上的火柴數為4﹑8﹑12﹑16…等讓乙去取,則甲
必穩操勝券。因此若原先桌面上的火柴數為15,則甲應取3根。(∵15-3=12)若原先桌面
上的火柴數為18呢?則甲應先取2根(∵18-2=16)。 
規則二:限制每次所取的火柴數目為1至4根,則又如何致勝? 
原則:若甲先取,則甲每次取時,須留5的倍數的火柴給乙去取。 
通則:有n支火柴,每次可取1至k支,則甲每次取後所留的火柴數目必須為k+1之倍數。 

規則三:限制每次所取的火柴數目不是連續的數,而是一些不連續的數,如1﹑3﹑7,則又
該如何玩法? 
分析:1﹑3﹑7均為奇數,由於目標為0,而0為偶數,所以先取者甲,須使桌上的火柴數為
偶數,因為乙在偶數的火柴數中,不可能再取去1﹑3﹑7根火柴後獲得0,但假使如此也不
能保證甲必贏,因為甲對於火柴數的奇或偶,也是無法依照己意來控制的。因為〔偶-奇=
奇,奇-奇=偶〕,所以每次取後,桌上的火柴數奇偶相反。若開始時是奇數,如17,甲先
取,則不論甲取多少(1或3或7),剩下的便是偶數,乙隨後又把偶數變成奇數,甲又把奇
數回覆到偶數,最後甲是注定為贏家;反之,若開始時為偶數,則甲注定會輸。 
通則:開局是奇數,先取者必勝;反之,若開局為偶數,則先取者會輸。 
規則四:限制每次所取的火柴數是1或4(一個奇數,一個偶數)。 
分析:如前規則二,若甲先取,則甲每次取時留5的倍數的火柴給乙去取,則甲必勝。此外
,若甲留給乙取的火柴數為5之倍數加2時,甲也可贏得遊戲,因為玩的時候可以控制每輪
所取的火柴數為5(若乙取1,甲則取4;若乙取4,則甲取1),最後剩下2根,那時乙只能
取1,甲便可取得最後一根而獲勝。 
通則:若甲先取,則甲每次取時所留火柴數為5之倍數或5的倍數加2。
 
遊戲規則: 
有一堆火柴兩人輪流取,先取的一方可任意取,後取的一方所取的火柴桿數不得超過對方
剛取火柴的2倍,規定取得最後一根者為勝。 
設火柴數為n,甲先取,乙後取 
當n=3:
若甲取1根剩2根,則乙全取──乙勝。

若甲取2根剩1根,則乙取最後1根──乙勝。

當n=5:
若甲取1根剩4根,則乙取1根剩3根換甲取,則乙必勝(如上n=3)。

若甲取2根剩3根,則乙全取──乙勝。

當n=8:
若甲取1根剩7根,則乙取2根剩5根讓甲取,則甲不利(如上n=5)──乙勝。

若甲取2根剩6根,則乙取1根剩5根如上,則對甲不利──乙勝。

若甲取3根剩5根,則乙可全取──乙勝。

若甲先取3根以上,情況如上──乙勝。

當n=13:
若甲取1根剩12根,則乙取1根剩11根,則

若甲接著取1根剩10根,則乙再取2根剩8根,對甲不利(如上)──故乙勝。
若甲接著取2根剩9根,則乙再取1根剩8根,對甲也不利(如上)──故乙勝。 
(註:甲不得接著取超過2根,因為上一次乙取1根。)

若甲取2根剩11根,則乙取3根剩8根,對甲不利──乙勝。

若甲取3根剩10根,則乙取2根剩8根,情況對甲不利──乙勝。

若甲取4根剩9根,則乙取1根剩8根,同樣對甲不利──乙勝。

若甲取5根剩8根,則乙可全取──乙勝。

若甲取5根以上,情況如上──乙勝。

由以上的例子中我們可觀察到,當火柴數為3﹑5﹑8﹑13…等時,對先取者不利。又從上面
例子,當n=13時,發現當火柴數為12時,先取者只要是取1根,必能立於不敗之地。 
事實上,此遊戲與著名的斐波南契數列有關,斐波南契數列係由13世紀初,義大利比薩的
數學家Leonardo Pisano(1170~1250)所提出,因其綽號為Fibonacci,故以其名之。斐
波南契在一本叫做算盤書(研究算術代數的書籍)中提出一個有趣的兔子問題: 
Q:假設最先有一對兔子,二個月後就能生育一對兔子,初生的兔子二個月後便具有生殖能
力,假設每對成熟具有生殖能力的兔子,每個月均能生育一對兔子,問一年後共有多少對
兔子?(如假設兔子都不死) 
假設Xn表n個月後兔子的對數,則X0=1,X1=1,X2=2,X3=3,X4=5,X5=8 且Xn+2=Xn+1+Xn
,n 30,故一年後(即12個月後)共有X12=233
--
#include<iostream>
using namespace std;
int a[100];
int binary_search(int left,int right,int goal)
{
    if(left<right)
    {
        int mid=(left+right)/2;
        if(a[mid]==goal) return mid;
        else if(a[mid]<goal) return binary_search(mid+1,right,goal);
        else return binary_search(left,mid,goal);
    }
    return -1;
}
int main()
{
    a[0]=2,a[1]=3;
    for(int i=2;i<25;i++) a[i]=a[i-1]+a[i-2];
    int n;
    while(cin>>n&&n)
    {
        if(binary_search(0,35,n)!=-1) cout<<"NO"<<endl;
        else cout<<"YES"<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值