• [agc010D]Decrementing-[。。。思考题]


    Description

    传送门

    Solution

     真是够神秘的啊。。。

    Alice和Bob两个真的城会玩。

    不过本题一个暗示挺明显的。就是黑板上所有数不论何时gcd为1。

    考场上我以为会很复杂,结果。。是我想多了qaq,人家就是用来判断奇偶性的。

    由于gcd为1,黑板上必定有一个数为奇数。

    假如n个数中偶数的个数为奇数,则先手必胜。

    先手可以将一个偶数变成奇数,然后后手做什么,就做对应的策略。(后手奇->偶,先手就偶->奇;后手偶->奇,先手还偶->奇)。

    因为我们保证在后手操作的时候偶数个数一定是偶数(好绕的说),所以不论什么时候先手都有对应的策略(如果后手动了偶数,肯定还有一个偶数给先手操作呢)。然后1是奇数,所以最后动不下去的肯定是后手啦。

    然后,假如黑板上偶数的个数为偶数,并且奇数的个数>1,则先手不管怎么动都会使得偶数个数为奇数,然后。。后手就稳赢了(参考上文)

    那如果奇数的个数为1呢?如果这个奇数本身就为1,先手肯定动不了它,那情况同上;如果奇数本身不为1,那就递归求解吧哈哈哈。。(反正也也递归不了多少次,每次所有数最少/2呢)

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    int n,a[100010],cnt=0,id;
    int gcd(int a,int b){if (!b) return a;return gcd(b,a%b);}
    bool dfs()
    {
        id=-1;cnt=0;
        for (int i=1;i<=n;i++) if (!(a[i]&1)) cnt++;else if (a[i]!=1) id=i;
        if (cnt&1) return 1;
        if (cnt!=n-1||(cnt==n-1&&id==-1)) return 0;
        a[id]--;int g=a[id];
        for (int i=1;i<=n;i++) g=gcd(g,a[i]);
        for (int i=1;i<=n;i++) a[i]/=g;
        return !dfs();
    }
    int main()
    {
        scanf("%d",&n);
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        printf("%s",dfs()?"First":"Second");
    }
  • 相关阅读:
    JavaScript Basic Memo
    移动端WEB开发备忘录
    重学前端
    roadhog 构建优化
    ES6 memo
    styled-components 背后的魔法
    怎么在多场景下使用不同的 git 账号 commit
    三方登录总结
    Promise 错误处理
    观察者模式 vs 发布-订阅模式
  • 原文地址:https://www.cnblogs.com/coco-night/p/9629998.html
Copyright © 2020-2023  润新知