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 }

转载于:https://www.cnblogs.com/Shirlies/archive/2012/03/09/2386187.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值