• 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 }
  • 相关阅读:
    第一次做Java程序注意事项
    数制学习笔记
    1228作业
    1226作业(转为十进制)
    [SDOI2010] 古代猪文 (快速幂+中国剩余定理+欧拉定理+卢卡斯定理) 解题报告
    Miller-Rabin
    STL整理之set
    [HNOI2008] GT考试(DP+矩阵快速幂+KMP)
    [JZOJ4024] [佛山市选2015] 石子游戏 解题报告
    [JZOJ3383] [NOIP2013模拟] 太鼓达人 解题报告(数位欧拉)
  • 原文地址:https://www.cnblogs.com/Shirlies/p/2386187.html
Copyright © 2020-2023  润新知