zoukankan      html  css  js  c++  java
  • P4018 Roy&October之取石子

    题目背景

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

    题目描述

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

    现在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。

    (改编题)

    看似这个题很复杂的样子,每一次可以在数里取走(为整数且p^k(k为整数,且ge 0))

    那这一看就是博弈论吧。于是考虑所有的必胜态。

    显然,当前这个数为(为质数p(p为质数))的次幂都可以必胜。

    那根据博弈观点,所有的通过一次到达上面状态的都是必败态。

    于是有下面的办法

    pri[maxn]//全为质数
    //cnt为选出的质数个数
    dp[1]=1;
    for(int k=2;k<=max;k++)
    for(int i=1;i<cnt;i++)
    	for(int j=1;j;j*=cnt[i])
    		if(!dp[k-j])dp[k]=1;
    

    这样就可以找出所有的数了。

    太慢了有木有。。。

    于是打表发现所有的必败态都是6的倍数

    于是

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    inline int read(){
        int an=0;
        char ch=getchar();
        while(ch<'0'||ch>'9'){ch=getchar();}
        while('0'<=ch&&ch<='9'){an=an*10+(ch^48);ch=getchar();}
        return an;
    }
    int n;
    int main(){
        ios::sync_with_stdio(0);
        n=read();
        for(;n;n--){
            int x=read();
            if(x%6)cout<<"October wins!
    ";
            else cout<<"Roy wins!
    ";
        }
        return 0;
    }
    

  • 相关阅读:
    算法导论2.37答案
    算法导论2.37的算法
    heavy dark读《《暗时间》》
    深入SetOP2函数
    c++标准库都有哪些文件
    c++ sort函数的用法
    深入char转换为int/unsigned int的内部机制分析
    顺序容器之vector
    java的动态代理机制详解
    java.lang.IllegalStateException: Web app root system property already set to different value
  • 原文地址:https://www.cnblogs.com/ck666/p/8097329.html
Copyright © 2011-2022 走看看