zoukankan      html  css  js  c++  java
  • [QSCOJ39]喵哈哈村的代码传说 第五章 找规律

    题目大意:
      给你n堆排,两人轮流对其中一堆牌进行以下操作之一:
        1.从这堆牌中取出任意数量的牌;
        2.将这这堆牌分为任意大小的3堆牌。
      不能操作者负。
      问先手是否有必胜策略。

    思路:
      尝试构造sg函数,游戏的状态为某堆牌中牌的数量,
      打表计算发现当x为8的倍数时,sg(x)=x-1;
      当x在模8意义下为7时,sg(x)=x+1;
      否则sg(x)=x。
      手算了以下x=0~8时的情况,解释如下:
      当x=0时,先手没法操作,sg(x)=0;
      当x=1时,当前的后继状态为(0),sg(x)=mex{sg(0)}=1;
      当x=2时,当前的后继状态为(0)(1),sg(x)=mex{sg(0),sg(1)}=2;
      当x=3时,当前的后继状态为(0)(1)(2)(1 1 1),sg(x)=mex{sg(0),sg(1),sg(2),...,sg(1)^sg(1)^sg(1)}=3;
      ……
      当x=7时,当前的后继状态为(0)~(6)(1 1 5)(1 2 4)(1 3 5)(2 2 3),此时(1 2 4)所对应的sg值为sg(1)^sg(2)^sg(4),sg(7)=8;
      而当x=8时,当前的后继状态中(7)的sg值为8,而其它的后继状态中sg值也没有等于7的,所以sg(x)=7。
      程序实现十分简单。

     1 #include<cstdio>
     2 #include<cctype>
     3 inline int getint() {
     4     register char ch;
     5     while(!isdigit(ch=getchar()));
     6     register int x=ch^'0';
     7     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
     8     return x;
     9 }
    10 inline int getsg(const int &x) {
    11     if(x%8==0) return x-1;
    12     if(x%8==7) return x+1;
    13     return x;
    14 }
    15 int main() {
    16     for(register int T=getint();T;T--) {
    17         int ans=0;
    18         for(register int n=getint();n;n--) {
    19             ans^=getsg(getint());
    20         }
    21         puts(ans?"First player wins.":"Second player wins.");
    22     }
    23     return 0;
    24 }
  • 相关阅读:
    hdu6761 Mininum Index // lyndon分解 + duval贪心 + 秦九韶算法
    hdu6762 Mow // 半平面交 模拟 双端队列
    数据库增删改查操作
    移动端自动化概念
    范围查询和模糊查询
    软件测试技能要求总结
    继承
    luogu_P2024 [NOI2001]食物链
    luogu_P4092 [HEOI2016/TJOI2016]树
    luogu_P2887 [USACO07NOV]防晒霜Sunscreen
  • 原文地址:https://www.cnblogs.com/skylee03/p/7611260.html
Copyright © 2011-2022 走看看