zoukankan      html  css  js  c++  java
  • 2017CCPC杭州-C. Hakase and Nano

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=6266

    以及pdf :http://acm.hdu.edu.cn/downloads/CCPC2018-Hangzhou-ProblemSet.pdf

    题意:给出 N 堆石头,每堆对应有 ai 个。其中A取时 取两次,B取时取一次(每次取时至少取一个,最多取完一堆)现在给出堆数以及对应的每堆个数,以及先后手关系(输入1代表A先手,输入2代表B先手)。问最后先手是否能取得胜利。

    思路:对于博弈问题,一般能找规律的找规律,不行就用sg函数。(...本弱鸡不会用sg函数写这个题)

    所以我们可以先对所有简单情况进行列举。同时,对于博弈问题,我们一定是要着重观察 先手对应的 P-position.即后手必胜,(或者说对于当前取的人必输的状态)。因为 P态只能转到N态 ,而 N至少有一种可能转到P 状态。所以只要找到 P 状态,则其他所有状态均为 先手获胜。

    对于石子问题,我们从最简单能判断的状态举例起:由于 全部为 1时取法是固定的 所以先观察全为1的状态:

    A先手:
    1       1 1      1 1 1    1 1 1 1   1 1 1 1 1 ...
    A赢      A赢      A输       A赢      A赢  
    所以全为1时,我们可以看到只要是 3 的倍数 A必输,即A处于P-position
    当不全为1时(X,Y,Z为任意数)
    X X Y 1 X Y 1 1 X Y ... 由此递推下去发现A不会再输了
    A赢 A赢 A赢(转换成1 1 1) A赢
    B先手:
    1 1 1 1 1 1 1 1 1 1 ... A输 A赢 A赢 A输 所以当全为1时,我们发现 只要是 n%3==1 则B能赢,否则会输
    当不全为1时(X,Y,Z为任意数)
    X X Y 1 1 X 1 1 X Y 1 1 1 X 1 1 1 1 X ...
    A输 A输 A输 A赢 A输(从1 1 X递推过来) A赢

    综上就会发现
    (1)A先手:当 全为 1 且个数 %3==0,则A输
    (2)B先手:当 1 的个数大于等于 n-1 时,且 n%3 == 1 A输,如果 1 的个数 为 n-1 且 n%3==0 时A输

    code:

    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <cmath>
    #define IOS ios::sync_with_stdio(0); cin.tie(0);
    #define mp make_pair
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int, int> pii;
    const double Pi = acos(-1.0);
    const double esp = 1e-9;
    const int inf = 0x3f3f3f3f;
    const int maxn = 1e3+7;
    const int maxm = 1e6+7;
    const int mod = 1e9+7;
    
    int main(){
        int T;
        cin>>T;
        while(T--){
            int n,m,tmp; 
            int cnt = 0;
            cin>>n>>m;
            for(int i=0;i<n;i++){
                scanf("%d",&tmp);
                if(tmp==1) cnt++;    
            }
            //当所有全为1,切n%3时
            if(m==1){
                if(cnt==n&&!(n%3))    cout<<"No"<<endl;
                else cout<<"Yes"<<endl;
            }else{
                if((cnt>=n-1&&(n%3)==1)||(cnt==n-1&&!(n%3))) cout<<"No"<<endl;
                else cout<<"Yes"<<endl;
            } 
            
        }
    }
  • 相关阅读:
    解决laravel Class 'DoctrineDBALDriverPDOMySqlDriver' not found 错误
    Ubuntu 服务器443端口证书配置
    服务器部署Apache+PHP+MYSQL+Laravel
    git 的常用命令
    Unity 2D 效应器与来回移动的实现
    Html5 Canvas介绍
    基于servlet+filter+反射模拟实现天猫首页的后端
    cleanCode[2]:函数编写的几大规则
    cleanCode[1]:有意义的命名
    学习JavaWeb aop两种配置方式
  • 原文地址:https://www.cnblogs.com/Tianwell/p/11469324.html
Copyright © 2011-2022 走看看