题意:给定一个数k,A和B两个人来博弈。从1A先开始,每次的动作是乘以[2,9]之间的一个整数,谁先把这个数乘到大于给定的k就算赢,问谁有必胜策略。
思路:博弈题最难描述清楚,一开始找规律,然后总结规律中的必然。(http://www.cnblogs.com/rainydays/archive/2011/09/07/2169471.html)能到达必败态的状态为必胜态,只能到达必胜态的状态为必败态。对于给定的k,n>=k时为必败态,所有能到达这些必败态的n为必胜态,这些必胜态中最小的是ceil(k/9.0)。凡是大于它的都可以直接到达必败态。然而有些状态只能到达必胜态,就是那些乘二都要进入必胜态的数字,这些数中最小的是ceil(ceil(k/9.0)/2.0)。这样我们又得到了一批必败态,我们只要按照这种方法不断地由必败推必胜,由必胜推必败,即可知道1是必败还是必胜。也就知道了stan是赢还是输了。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
unsigned int n;
int test(unsigned int n){
if((n = (int)ceil(n/9.)) == 1)
return 1;
if((n = (int)ceil(n/2.)) == 1)
return 0;
return test(n);
}
int main(){
while(scanf("%u",&n)!=EOF){
if(test(n))
printf("Stan wins.\n");
else
printf("Ollie wins.\n");
}
}