• 【Atcoder Grand Contest 010】D


    题目链接

    题目大意:给定n个最大公约数为1的整数,两个人轮流进行操作,每次操作可以选一个大于1的数使其减1,然后所有的数再除以当前的最大公约数(如3 6 10对10操作后得到1 2 3),当其中一个人无法操作时,输掉比赛,求获胜的是先手还是后手。先手输出First,后手输出Second。


    分析:

    我们先想一下,如何能使整段序列变成全为1,很显然只有当序列变为形如k,k,k,k,k+1才能一步变为全为1的序列。那么另一个人一定会避免让对手拿到这样的序列(可以通过操作别的数使得不会出现这种情况),当且仅当k=1时,才能决出胜负。

    也就是说,*获胜的一方一定会拿到形如1,1,1,1,2的序列(性质1)。

    一、当偶数的个数为奇数时:

    (1)当n>2时,先手可以通过选数来使得gcd一直为1。如果此时gcd一直为1会发生什么呢?

      因为两人各选一次后偶数个数奇偶性不变,那么先手是一定获胜的(参考性质1)。

    (2)当n=2时,先手可能无法避免出现除法(会出现两数同为奇数的情况),此时会出现除以奇数的情况。

      奇数除以奇数还是奇数,因此 奇偶性依然不会变,所以先手依然必胜。

    *当偶数的个数为奇数时,先手必胜(性质2)。

    二、当偶数的个数为偶数时,先手要利用先手的优势尝试扭转偶数个数的奇偶性:唯一扭转个数奇偶性的方法就是同除一个偶数,这样的话偶数可能变成奇数,当然也可能还是偶数。

    (1)*当奇数个数大于1或奇数中存在1时,无法逆转,先手必败(性质3)。

    (2)当奇数个数为1且该奇数不为1时,递归模拟,当出现操作后偶数个数为奇数的时候,

      说明此操作的执行者必败(参考性质2);当序列中出现1或奇数个数大于1时,逆转不可能再发生了,可以直接得出答案。

    *当偶数个数为偶数,奇数个数为1且此奇数不为1时,先手有可能获胜,也有可能输掉比赛(性质4)。


    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 const int N=1e5+10;
     5 int a[N],ma=0,n;
     6 int read(){
     7     int ans=0,f=1;char c=getchar();
     8     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     9     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
    10     return ans*f;
    11 }
    12 /*-----------------------------------------------------*/
    13 int gcd(int x,int y){return !y?x:gcd(y,x%y);}
    14 bool dfs(int p){
    15     int mc=0,flag=1;
    16     for(int i=1;i<=n;i++)if(a[i]%2){a[i]--;break;}
    17     int gc=a[1];
    18     for(int i=2;i<=n;i++)gc=gcd(gc,a[i]);
    19     for(int i=1;i<=n;i++){a[i]/=gc;if(!(a[i]%2))mc++;if(a[i]==1)flag=0;}
    20      if(mc%2)return !p;
    21     if(!flag||n-mc!=1)return p;
    22     return dfs(p^1);
    23 }
    24 int main(){
    25     n=read();int mc=0;bool flag=1;
    26     for(int i=1;i<=n;i++){
    27         a[i]=read();if(a[i]%2==0)mc++;
    28         else {
    29             ma++;if(a[i]==1)flag=0;
    30         }
    31     } 
    32     if(mc%2)printf("First");
    33     else {
    34         if(ma!=1||!flag)printf("Second");
    35         else if(dfs(1))printf("First");
    36         else printf("Second");
    37     }
    38     return 0;
    39 }
    agc010 D
  • 相关阅读:
    解决Manjaro i3社区版 compton默认配置不正确的问题
    Manjaro 18.1.5 i3社区版安装后初步配置
    Manjaro Linux 18 中安装配置搜狗拼音输入法
    博客园美化(最全)
    vritulbox中linux安装zookeeper报错:
    eclipse中springmvc框架出现404
    ajax
    JSP
    请求转发和重定向的区别:
    本周授课内容:http,https,Tomcat,servlet
  • 原文地址:https://www.cnblogs.com/JKAI/p/7599877.html
Copyright © 2020-2023  润新知