取(m堆)石子游戏

Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 4610 Accepted Submission(s): 2775

Problem Description

m堆石子,两人轮流取.只能在1堆中取.取完者胜.先取者负输出No.先取者胜输出Yes,然后输出怎样取子.例如5堆 5,7,8,9,10先取者胜,先取者第1次取时可以从有8个的那一堆取走7个剩下1个,也可以从有9个的中那一堆取走9个剩下0个,也可以从有10个的中那一堆取走7个剩下3个.

Input

输入有多组.每组第1行是m,m<=200000. 后面m个非零正整数.m=0退出.

Output

先取者负输出No.先取者胜输出Yes,然后输出先取者第1次取子的所有方法.如果从有a个石子的堆中取若干个后剩下b个后会胜就输出a b.参看Sample Output.

Sample Input

  1. 2
  2. 45 45
  3. 3
  4. 3 6 9
  5. 5
  6. 5 7 8 9 10
  7. 0

Sample Output

  1. No
  2. Yes
  3. 9 5
  4. Yes
  5. 8 1
  6. 9 0
  7. 10 3

思路

可以看出这是典型的Nim博弈

对于先手必败的情况,直接输出No就行了

对于先手必胜,我们需要让先手第一次取走后剩下的石子保证奇异局势为0(即后手拿的时候必败)的状态。

输出的时候,让原本的奇异局势与当前堆的石子数异或,如果异或结果小于等于当前石子数,输出即可

AC代码

  1. /*
  2. * @Author: WZY
  3. * @School: HPU
  4. * @Date: 2019-01-03 16:54:58
  5. * @Last Modified by: WZY
  6. * @Last Modified time: 2019-01-03 17:21:29
  7. */
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <iostream>
  11. #include <algorithm>
  12. #include <math.h>
  13. #include <limits.h>
  14. #include <map>
  15. #include <stack>
  16. #include <queue>
  17. #include <vector>
  18. #include <set>
  19. #include <string>
  20. #include <time.h>
  21. #define ll long long
  22. #define ull unsigned long long
  23. #define ms(a,b) memset(a,b,sizeof(a))
  24. #define pi acos(-1.0)
  25. #define INF 0x7f7f7f7f
  26. #define lson o<<1
  27. #define rson o<<1|1
  28. #define bug cout<<"---------"<<endl
  29. #define debug(...) cerr<<"["<<#__VA_ARGS__":"<<(__VA_ARGS__)<<"]"<<"\n"
  30. const double E=exp(1);
  31. const int maxn=1e6+10;
  32. const int mod=1e9+7;
  33. using namespace std;
  34. int a[maxn];
  35. int main(int argc, char const *argv[])
  36. {
  37. ios::sync_with_stdio(false);
  38. #ifndef ONLINE_JUDGE
  39. freopen("in.txt", "r", stdin);
  40. freopen("out.txt", "w", stdout);
  41. double _begin_time = clock();
  42. #endif
  43. int n;
  44. while(cin>>n&&n)
  45. {
  46. int ans=0;
  47. for(int i=0;i<n;i++)
  48. {
  49. cin>>a[i];
  50. ans^=a[i];
  51. }
  52. if(!ans)
  53. cout<<"No"<<endl;
  54. else
  55. {
  56. cout<<"Yes"<<endl;
  57. for(int i=0;i<n;i++)
  58. {
  59. if((ans^a[i])<=a[i])
  60. cout<<a[i]<<" "<<(ans^a[i])<<endl;
  61. }
  62. }
  63. }
  64. #ifndef ONLINE_JUDGE
  65. double _end_time = clock();
  66. printf("time = %lf ms.", _end_time - _begin_time);
  67. #endif
  68. return 0;
  69. }

HDU 2176:取(m堆)石子游戏(Nim博弈)的更多相关文章

  1. HDU 2176 取(m堆)石子游戏(Nim)

    取(m堆)石子游戏 题意: Problem Description m堆石子,两人轮流取.只能在1堆中取.取完者胜.先取者负输出No.先取者胜输出Yes,然后输出怎样取子.例如5堆 5,7,8,9,1 ...

  2. 杭电 2176 取(m堆)石子游戏(博弈)

    取(m堆)石子游戏 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  3. HDU 2176 取(m堆)石子游戏 —— (Nim博弈)

    如果yes的话要输出所有情况,一开始觉得挺难,想了一下也没什么. 每堆的个数^一下,答案不是0就是先取者必胜,那么对必胜态显然至少存在一种可能性使得当前局势变成必败的.只要任意选取一堆,把这堆的数目变 ...

  4. HDU 2176 取(m堆)石子游戏 (尼姆博奕)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2176 m堆石子,两人轮流取.只能在1堆中取.取完者胜.先取者负输出No.先取者胜输出Yes,然后输出怎 ...

  5. HDU 2176 取(m堆)石子游戏 && HDU1850 Being a Good Boy in Spring Festivaly

    HDU2176题意: m堆石子,两人轮流取.只能在1堆中取.取完者胜.先取者负输出No.先取者胜输出Yes,然后输出怎样取子. 通过 SG定理 我们可以知道每一个数的SG值,等于这个数到达不了的前面数 ...

  6. hdu 2176 取(m堆)石子游戏 (裸Nim)

    题意: m堆石头,每堆石头个数:a[1]....a[m]. 每次只能在一堆里取,至少取一个. 最后没石子取者负. 先取者负输出NO,先取胜胜输出YES,然后输出先取者第1次取子的所有方法.如果从有a个 ...

  7. HDU 2176 取(m堆)石子游戏 尼姆博弈

    题目思路: 对于尼姆博弈我们知道:op=a[1]^a[2]--a[n],若op==0先手必败 一个简单的数学公式:若op=a^b 那么:op^b=a: 对于第i堆a[i],op^a[i]的值代表其余各 ...

  8. HDU 2176 取(m堆)石子游戏(尼姆博奕)

    nim基础博弈 #include<stdio.h> #include<iostream> #include<cstring> #include<queue&g ...

  9. HDU 2177 取(2堆)石子游戏

    取(2堆)石子游戏 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

随机推荐

  1. http短连接与长连接简介

    1.HTTP协议与TCP/IP协议的关系 HTTP的长连接和短连接本质上是TCP长连接和短连接.HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议.IP协议主要解决网络路由和寻址问题 ...

  2. tomcat启动正常,但是访问项目时,404. Eclipse没有正确部署工程项目

    解决方案URL:http://blog.csdn.net/lynn_wgr/article/details/7751228

  3. open() 文件读写简要记录

  4. c# 关于Threading.ApartmentState

    今天在做一个需求 就是 客户端的注销重新登录的操作,想必大家很清楚这个逻辑应该怎么去做, 在主线程里面去调用这个注销的方法 然后关闭当前应用域,重新开一个线程 让应用域在上面执行. STA(singl ...

  5. 泛型的上下边界 : ? extends E 与 ? super T

    public class Problem { public static void main(String[] args) { List<? extends A> list; List&l ...

  6. L1-061 新胖子公式

    根据钱江晚报官方微博的报导,最新的肥胖计算方法为:体重(kg) / 身高(m) 的平方.如果超过 25,你就是胖子.于是本题就请你编写程序自动判断一个人到底算不算胖子. 输入格式: 输入在一行中给出两 ...

  7. easyui datagrid 后台分页,前端如何处理

    module.exports = { queryMethod(){ let params = checkQueryParams.call(this); if (!params) { return; } ...

  8. 深圳奥特迅现金流量——RESSET数据库

    现金流不好,很多年都是负数.到公司官方网站上收集信息,拳头产品有矩阵柔性充电堆,主要盈利产品有电源和电源管理系统.还承担了深圳市的充电桩交钥匙项目. 下面是它这些年的股价,在大牛市的时候也上升至五十几 ...

  9. python初学代码留个纪念

    最简单的代码  if   else if  else 1.python中else if   用  elif表示 2.注释: 单行注释:##### 多行注释:''' ------''',"&q ...

  10. Java垃圾回收机制和注解