zoukankan      html  css  js  c++  java
  • hdu 1850

    这是一道关于博弈的题目,这一题挺不错的,如果知道了nim游戏异或的道理,这一题是比较好写的。

    Nim游戏的局面(a1,a2,...,an),它是P-position当且仅当a1^a2^...^an=0,其中^表示异 (xor)运算。
    •对于某个局面(a1,a2,...,an),若a1^a2^...^an==k(k>0)
    •一定存在某个合法的移动,将ai改变成ai'后满足 a1^a2^...^ai'^...^an=0
    •一定存在某个ai,它的二进制表示在k的最高位上是1 (ai^k<ai 成立)
    •将ai改变成ai'=ai^k a1^a2^...^ai'^...^an=a1^a2^...^an^k=0
     有了这个,我们就可以直接找含有最高位为1的值就可以了,但是一定要注意,找到最高位为1后还要判断ai^k<ai,因为有可能有K值的最高位并不是在ai中,譬如k=1,10^K>10.我就是因为之前没有考虑这个,很悲剧的WA了两次(其中有一次是范围有问题我找出来后还是WA^_^)
    View Code
     1 #include <cstdio>
    2 #include <algorithm>
    3 using namespace std;
    4
    5 int heap[120];
    6
    7 int main()
    8 {
    9 int m;
    10 while(scanf("%d",&m) == 1)
    11 {
    12 if(!m)
    13 break;
    14 int i;
    15 int sum = 0;
    16 for(i = 0;i < m;i ++)
    17 {
    18 scanf("%d",&heap[i]);
    19 sum ^= heap[i];
    20 }
    21 if(sum == 0)
    22 {
    23 printf("0\n");
    24 continue;
    25 }
    26 sort(heap,heap + m);
    27 int k = 0;
    28 int n = sum;//记录sum的值以备后用
    29 while(sum)
    30 {
    31 sum>>=1;
    32 k ++;//记录sum的位数
    33 }
    34 int t;
    35 t = 1 << (k - 1);//计算最高位为1的最小值
    36 //printf("k:%d;t:%d\n",k,t);
    37 k = 0;
    38 for(i = m-1;i >= 0;i --)
    39 {
    40 if(heap[i] < t)
    41 break;
    42 if(heap[i] >= t&&(heap[i]^n )< heap[i])//一定要用(heap[i]^n )< heap[i],并注意异或的优先级
    43 k ++;
    44 }
    45 printf("%d\n",k);
    46 }
    47 return 0;
    48 }
  • 相关阅读:
    个人编写的一个简单的DB类
    Access绝对地址
    sentry cli 上传source map
    自动旋转的饼图(echarts)
    点会转的折线图还带着柱子
    node 自动化工程部署
    SQL 模糊查询
    编写一个将输入复制到输出的程序,并将其中连续的多个空格用一个空格代替。
    configure、make、make install 解释
    Linux学习笔记(实时更新)
  • 原文地址:https://www.cnblogs.com/Shirlies/p/2386187.html
Copyright © 2011-2022 走看看