「POJ2505」A multiplication game [博弈论]
题目链接: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 }
谢谢大家支持。
如何可以指出我有哪些写得不好的地方,本人感激不尽!!