题目把Nim游戏为什么可以取异或和讲解得十分清楚,建议多读几次,理解一下

再一个,可以把每次异或视为一次取数,因此(k[i]^sg)<k[i]即为一种可行操作

/*
Nim is a 2-player game featuring several piles of stones.
Players alternate turns, and on his/her turn, a player’s
move consists of removing one or more stones from any
single pile. Play ends when all the stones have been
removed, at which point the last player to have moved is
declared the winner. Given a position in Nim, your task
is to determine how many winning moves there are in that
position. A position in Nim is called “losing” if the first player
to move from that position would lose if both sides played
perfectly. A “winning move,” then, is a move that leaves
the game in a losing position. There is a famous theorem
that classifies all losing positions. Suppose a Nim position
contains n piles having k1, k2, …, kn stones respectively;
in such a position, there are k1 + k2 + … + kn possible
moves. We write each ki in binary (base 2). Then, the Nim
position is losing if and only if, among all the ki’s,
there are an even number of 1’s in each digit position.
In other words, the Nim position is losing if and only if
the xor of the ki’s is 0. Consider the position with three piles given by k1 = 7, k2
= 11, and k3 = 13. In binary, these values are as follows: 111
1011
1101 There are an odd number of 1’s among the rightmost digits,
so this position is not losing. However, suppose k3 were
changed to be 12. Then, there would be exactly two 1’s in
each digit position, and thus, the Nim position would become
losing. Since a winning move is any move that leaves the
game in a losing position, it follows that removing one
stone from the third pile is a winning move when k1 = 7, k2
= 11, and k3 = 13. In fact, there are exactly three winning
moves from this position: namely removing one stone from any
of the three piles.
*/
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n,k[];
int main(){
while(scanf("%d",&n)){
if(n==)break;
int sg=,ans=;
for(int i=;i<=n;i++)scanf("%d",&k[i]),sg^=k[i];
for(int i=;i<=n;i++)if((k[i]^sg)<k[i])ans++;
printf("%d\n",ans);
}
return ;
}

最新文章

  1. sql语句,order by
  2. MVC 缓存
  3. C# 非托管内存使用时的注意事项
  4. jqgrid在colModel中多次调用同一个字段值
  5. jquery 学习
  6. STM32 ucosii 串口接收数据 遇到的问题及解决思路
  7. 这些小众软件让你的效率提升N倍!(必备,收藏)
  8. module_init宏解析
  9. 实现Runnable接口和扩展Thread使用场景
  10. DeepLearning.ai学习笔记(四)卷积神经网络 -- week1 卷积神经网络基础知识介绍
  11. 华科机考:N阶楼梯上楼
  12. Git之(六)标签管理
  13. 修改MAC地址的方法 破解MAC地址绑定(抄)
  14. C# Selenium学习
  15. 在Windows Server 2008 R2 Server中,上传视频遇到的问题(二)
  16. 使用keepalived实现双机热备
  17. AppScan--图解Web扫描工具IBM Security App Scan Standard
  18. Hadoop hostname: Unknown host
  19. 神经网络中的池化层(pooling)
  20. 【HNOI2015】落忆枫音

热门文章

  1. 基于java开发jsp+ssm+mysql实现的在线考试系统 源码下载
  2. java Spring boot Docker打包
  3. Centos 7 firewall的防火墙的规则
  4. JN_0018:运行窗口不显示
  5. Java细节1--输入关闭
  6. swiper快速切换插件(两个综合案例源码)
  7. sublime 下载 和 破解
  8. win10家庭版更改本地账户名、C盘Users下文件夹名和环境变量等
  9. 网络共享服务(三)之SAMBA
  10. pcl库卸载再重装