題目鏈接:http://poj.org/problem?id=2505 題目大意: 兩個人輪流玩游戲,Stan先手,數字 p從1開始,Stan乘以一個2-9的數,然後Ollie再乘以一個2-9的數,直到誰先將p乘到p>=n時那個人就贏了,而且輪到某人時,某人必須乘以2-9的一個數。 解題思路: 這是 ...
題目鏈接:http://poj.org/problem?id=2505
題目大意:
兩個人輪流玩游戲,Stan先手,數字 p從1開始,Stan乘以一個2-9的數,然後Ollie再乘以一個2-9的數,直到誰先將p乘到p>=n時那個人就贏了,而且輪到某人時,某人必須乘以2-9的一個數。
解題思路:
這是一道博弈論的題目。
不過這道題並沒有用SG函數相關的知識。
首先我們可以很快判斷區間[2,9]必定是先手勝
然後緊接著是區間[10,18]區間是後手勝
然後是什麼呢?
[18,??]
我們可以這樣來理解:
我們可以考慮一下,先手是要取勝,就是要越大越好,越大越快,
所以每次輪到先手進行操作時,肯定是要乘上最大的哪一個數,也就是9
那麼我們反過來,後手就是要儘量拖住先手,所以每一次都會乘上哪一個最小的數,也就是2
於是,這樣的話我們就可以將區間補出來:
[2,9]
[9+1,9*2]
[9*2+1,9*2*9]
[9*2*9+1,9*2*9*2]
.......
所以著一道題我們就可以做了吧。
至於怎麼操作,我用的方法並不是最快的,但是應該是比較清楚的。
定義l,r為2,9然後按照上面模擬即可,然後每次判斷就行
額。。。網上有題解說他們是找規律找出來的,我連找規律都不會找。。。。。推了好久才推出來。。。
無語。。。
貼代碼:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 typedef long long ll; 6 ll n; 7 int main() 8 { 9 while(scanf("%lld",&n)==1) 10 { 11 ll l=2; 12 ll r=9; 13 int flag=1; 14 while(true) 15 { 16 if(n>=l&&n<=r) 17 { 18 if(flag==1) printf("Stan wins.\n"); 19 else printf("Ollie wins.\n"); 20 break; 21 } 22 else{ 23 l=r+1; 24 if(flag==1) 25 { 26 r=r*2; 27 flag=0; 28 } 29 else 30 { 31 flag=1; 32 r=r*9; 33 } 34 } 35 } 36 } 37 return 0; 38 }
謝謝大家支持。
如何可以指出我有哪些寫得不好的地方,本人感激不盡!!