题意:给定上限 n ,令 p=1,每次可以从 [2,9] 中选择一个数乘上 p 然后构成新的 p ,若 p >= n 则次回合玩家胜利,求先后手哪个必胜;
分析:首先得知道一点:能到达必败态的状态为必胜态,只能到达必胜态的状态为必败态。
① [ ceil(n/9) , n-1 ] 内的所有数都是必胜态,因为下一步可以达到必败态,即p>=n ; //ceil()是向上取整
② [ ceil(n/9/2) , ceil(n/9)-1 ] 内的所有数都是必败态,因为他们只能达到必胜态;
由此我们可以不断进行上述两个操作判断先手必胜还是后手必胜;
代码:
#include<cmath>
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
bool K(ll n){
while(1){
if((n=ceil(n/9.0))==1) return 1;
if((n=ceil(n/2.0))==1) return 0;
}
}
int main()
{
ll n;
while(~scanf("%lld",&n)){
if(K(n)) puts("Stan wins.");
else puts("Ollie wins.");
}
}