• 「CF1382B」Sequential Nim


    • 题目大意

      (n) 堆石子,第 (i) 堆有 (a_i) 个。有两个人在玩取石子游戏。

      两个人轮流取石子,每次取编号最小且有石子的堆。每个人可以在一堆石子中取走若干个(至少取 (1) 个),当一个人没有石子可以取了,他就输了。

      现在给出每堆石子的数量,假设两人的都采用最优策略,问最后是先手 (first) 胜利还是后手 (second) 胜利。

    • 分析

      我们可以发现对于若干堆(第一堆数量大于 (1),有这么一个贪心的取法:

      比如第一堆堆数量为 (n(n>1))先手先取 (n-1) 个。这样后手只能取 (1) 个(无法不取)。

      这样,先手就可以先取第二堆

      后几堆的取法同上,直到先手可以先取最后一堆。

      对于最后一堆,先手直接取完。获胜。

      那如果中间有一堆数量为 (1) 那么对于这一堆的前一堆,直接全部取完,后手只能取完这堆数量为 (1) 的堆。照样可以获得下一堆的先手

      以此类推。我们可以发现,影响最后结果的,只有前缀 (1) 的数量。

      容易发现,如果前缀 (1) 数量为偶数个,在轮流取完后,那么第一个非 (1) 堆,是先手先取。即先手会胜利。

      如果是奇数个,那么第一个非 (1) 堆,是后手先取。即后手会胜利。

      特殊的,如果这堆只有 (1)那么偶数个胜利的为后手奇数个胜利的为先手


    • 代码

      #include<iostream>
      #include<cstdio>
      #include<cstring>
      using namespace std;
      const int Maxn=1e5+5;
      int T,n,a[Maxn];
      int main()
      {	
          scanf("%d",&T);
          while(T--)
          {	
              int cnt=0,i;
              scanf("%d",&n);
              for(i=1;i<=n;i++)
                  scanf("%d",&a[i]);
              for(i=1;i<=n;i++)
                  if(a[i]==1)cnt++;
                  else break;
              if(i==n+1)
              {	
                  if(cnt%2==0)printf("Second
      ");
                  else printf("First
      ");
              }
              else{
                  if(cnt%2==0)printf("First
      ");
                  else printf("Second
      ");
              }
          }
          return 0;
      }
      
  • 相关阅读:
    第2章 医疗检查安全吗?推荐!
    第3章 药物对你有何影响
    基础篇 第二节 项目管理的知识点
    第1章 简介
    魔兽争霸 意志亡灵Space专访:20岁就要死去
    第八章 陶穆太太 第九章 冒险经历 第十章 在旧地下室里
    第4章 医生在利用你试验新药吗
    第十二章 陶穆太太归来
    第十一章 爸爸妈妈不明白……
    <a>锚链接的功能取消
  • 原文地址:https://www.cnblogs.com/Rainy7/p/13424703.html
Copyright © 2020-2023  润新知