• 【BZOJ1299】巧克力棒(Nim游戏,SG函数)


    题意:TBL和X用巧克力棒玩游戏。每次一人可以从盒子里取出若干条巧克力棒,或是将一根取出的巧克力棒吃掉正整数长度。

    TBL先手两人轮流,无法操作的人输。

    他们以最佳策略一共进行了10轮(每次一盒)。你能预测胜负吗?

    如果TBL胜则输出”NO”,否则输出”YES”

    n<=14,a[i]<=1e9

    思路:一个结论:Nim游戏中一个xor和不为0(先手必胜)的状态一定可以通过1步转化为xor和为0(先手必败)的状态

    所以先手第一步只需要取出一个xor和为0的最长子序列

    若后手选择加入新巧克力棒,先手可以通过1步将已经加入的Nim游戏变为xor和为0的局面

    若后手选择取已经加入的部分,先手依然可以通过1步将后手行动过的局面的xor和变为0

    所以只需要判断初始局面下存不存在xor和为0的子序列

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cmath>
     6 typedef long long ll;
     7 using namespace std;
     8 #define N   210000
     9 #define oo  10000000
    10 #define MOD 1000000007
    11 
    12 int a[N],b[N],f[N];
    13 
    14 int lowbit(int x)
    15 {
    16     return x&(-x);
    17 }
    18 
    19 int main()
    20 { 
    21     for(int v=1;v<=10;v++)
    22     {
    23         int n;
    24         scanf("%d",&n);
    25         for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    26         int x=1;
    27         for(int i=1;i<=n;i++)
    28         {
    29             b[x]=i;
    30             x<<=1;
    31         }
    32         f[0]=0;
    33         for(int i=1;i<=(1<<n)-1;i++) f[i]=f[i^lowbit(i)]^a[b[lowbit(i)]];
    34         int ans=0;
    35         for(int i=1;i<=(1<<n)-1;i++)
    36          if(!f[i]) ans=1;
    37         if(ans) printf("NO
    ");
    38          else printf("YES
    ");
    39     }        
    40     return 0;
    41 }
    42     
  • 相关阅读:
    java设计模式演示样例
    一步一步写算法(之排序二叉树)
    收集经常使用的.net开源项目
    jdbc连接数据库
    Android开发系列(二十二):AdapterViewFlipper的功能和使用方法
    ProgressDialog使用总结
    HDU 4916 树分治
    [Unity3D]自制UnityForAndroid二维码扫描插件
    IOS ARC和非ARC文件混用
    让子弹飞Demo版
  • 原文地址:https://www.cnblogs.com/myx12345/p/9954364.html
Copyright © 2020-2023  润新知