P4018 Roy&October之取石子

Posted five20

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P4018 Roy&October之取石子相关的知识,希望对你有一定的参考价值。

 

题目背景

 

Roy和October两人在玩一个取石子的游戏。

 

题目描述

 

游戏规则是这样的:共有n个石子,两人每次都只能取 p^kpk 个(p为质数,k为自然数,且 p^kpk 小于等于当前剩余石子数),谁取走最后一个石子,谁就赢了。

 

现在October先取,问她有没有必胜策略。

 

若她有必胜策略,输出一行"October wins!";否则输出一行"Roy wins!"。

 

输入输出格式

输入格式:

 

 

第一行一个正整数T,表示测试点组数。

 

第2行~第(T+1)行,一行一个正整数n,表示石子个数。

 

 

输出格式:

 

 

T行,每行分别为"October wins!"或"Roy wins!"。

 

 

 

输入输出样例

 

输入样例#1: 
3
4
9
14
输出样例#1: 
October wins!
October wins!
October wins!

 

说明

 

对于30%的数据,1<=n<=30;

 

对于60%的数据,1<=n<=1,000,000;

 

对于100%的数据,1<=n<=50,000,000,1<=T<=100,000。

 

(改编题)

 

 

Solution:

  本题比较水。

  首先,不难发现$1,2,3,4,5$都是先手赢,到了$6$时就后手赢了,而对于大于$6$小于$12$的数,都能取$[1,5]$中的某个数,使其变为$6$,而到了$12$又是后手赢…

  直接告诉我们,$6$的倍数是先手必输状态,其余为先手必胜状态。

  首先,$6$的倍数一定不是某一质数的幂(这是显然的,因为$6=2 imes 3$,所以$6$的倍数至少含两个质因子),所以$6$的倍数一定不能被一次取完。

  然后无论$6$的倍数怎么取,都至少取走一个非$6$的倍数的数,那么剩下的数必定为非$6$的倍数的数,我们只要从$[1,5]$中取某个值就能使得其又变为$6$的倍数。

  最后一定能够回到值为$6$且后手取的情况,此时后手无论取何值,都是输。

  所以只需判断一下是否是$6$的倍数就好了。

代码:

 

 1 #include<bits/stdc++.h>
 2 #define il inline
 3 #define ll long long
 4 #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
 5 #define Bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--)
 6 #define Max(a,b) ((a)>(b)?(a):(b))
 7 #define Min(a,b) ((a)>(b)?(b):(a))
 8 using namespace std;
 9 int T,n;
10 
11 il int gi(){
12     int a=0;char x=getchar();bool f=0;
13     while((x<0||x>9)&&x!=-)x=getchar();
14     if(x==-)x=getchar(),f=1;
15     while(x>=0&&x<=9)a=(a<<3)+(a<<1)+x-48,x=getchar();
16     return f?-a:a;
17 }
18 
19 int main(){
20     T=gi();
21     while(T--){
22         n=gi();
23         if(n%6==0)puts("Roy wins!");
24         else puts("October wins!");
25     }
26     return 0;
27 }

 

以上是关于P4018 Roy&October之取石子的主要内容,如果未能解决你的问题,请参考以下文章

洛谷 Roy&October之取石子

Roy&October之取石子

Roy&October之取石子II

ACM-尼姆博弈之取(m堆)石子游戏——hdu2176

NOIP题目解析之取石子问题

[codevs1048]石子归并&&[codevs2102][洛谷P1880]石子归并加强版