NC50615 取石子游戏 2
题目
题目描述
有一种有趣的游戏,玩法如下:
玩家:2人;
道具:N堆石子,每堆石子的数量分别为 \(X_1,X_2,...,X_n\) ;
规则:
- 游戏双方轮流取石子;
- 每人每次选一堆石子,并从中取走若干颗石子(至少取1颗);
- 所有石子被取完,则游戏结束;
- 如果轮到某人取时已没有石子可取,那此人算负。
假如两个游戏玩家都非常聪明,问谁胜谁负?
输入描述
第一行,一个整数N;
第二行,N个空格间隔的整数 \(X_i\) ,表示每一堆石子的颗数。
输出描述
输出仅一行,一个整数,若先手获胜输出win,后手获胜输出lose。
示例1
输入
4
7 12 9 15
输出
win
备注
对于全部数据,\(N \leq 5 \times10^4,1 \leq X_i \leq 10^5\) 。
题解
知识点:博弈论。
经典的Nim游戏,当所有石子数的异或和为 \(0\) 先手必败,否则必胜。
我们设 \(\displaystyle \bigoplus_{i=1}^n a_i = 0\) 时为必败态,否则为必胜态(这里只是假设,字面上的意义还需要证明),考虑证明:
游戏终止状态为必败态:
终止状态为全 \(0\) ,满足我们的假设。
必败态只能转到必胜态:
假设存在合法操作使得必败态转到必败态,那么存在一个石子堆被改变了,不妨设它新的数量为 \(a_i'\) ,设其他没有改变的石子堆的异或和为 \(sum\) ,我们可以得到 \(sum \oplus a_i' = sum \oplus a_i = 0\) ,最后 \(a_i' = a_i\) 矛盾。
因此必败态只能转到必胜态。
必胜态可以转到必败态:
我们设当前异或和为 \(sum\) ,设 \(sum\) 二进制最高位为第 \(k\) 位,那么一定存在一个石子堆的数量二进制第 \(k\) 位为 \(1\) ,不妨假设这堆石子为 \(a_i\) 。此时,我们有 \(a_i \oplus sum < a_i\) ,因为 \(sum\) 不会改变 \(a_i\) 更高位的状态,但会使得 \(a_i\) 的第 \(k\) 位变为 \(0\) 。那么,我们可以从 \(a_i\) 中拿出 \(a_i - (a_i \oplus sum)\) 个石子,此时 \(a_i \to a_i \oplus sum\) ,于是异或和就变为 \(sum \oplus sum = 0\) 。
因此必胜态可以转到必败态。
综上,我们证明了我们假设的必胜态和必败态确实是实际意义上的必胜和必败,并且这是一个构造性证明。
时间复杂度 \(O(n)\)
空间复杂度 \(O(n)\)
代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n;
cin >> n;
int sum = 0;
for (int i = 1;i <= n;i++) {
int x;
cin >> x;
sum ^= x;
}
cout << (sum ? "win" : "lose") << '\n';
return 0;
}
NC50615 取石子游戏 2的更多相关文章
- Games:取石子游戏(POJ 1067)
取石子游戏 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 37662 Accepted: 12594 Descripti ...
- HDU 2516 取石子游戏(斐波那契博弈)
取石子游戏 Time Limit: 2000/1000 MS(Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submissi ...
- hdu 1527 取石子游戏(Wythoff Game)
题意:Wythoff Game 思路:Wythoff Game #include<iostream> #include<stdio.h> #include<math.h& ...
- HDU 2516 取石子游戏(FIB博弈)
取石子游戏 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- 1874: [BeiJing2009 WinterCamp]取石子游戏 - BZOJ
Description小H和小Z正在玩一个取石子游戏. 取石子游戏的规则是这样的,每个人每次可以从一堆石子中取出若干个石子,每次取石子的个数有限制,谁不能取石子时就会输掉游戏. 小H先进行操作,他想问 ...
- HDU-1527 取石子游戏
http://acm.hdu.edu.cn/showproblem.php?pid=1527 交换 :可实现. if( n < m ) { n^=m; m^=n; n^=m; } (三)尼姆博 ...
- bzoj 1874 取石子游戏 题解 & SG函数初探
[原题] 1874: [BeiJing2009 WinterCamp]取石子游戏 Time Limit: 5 Sec Memory Limit: 162 MB Submit: 334 Solved ...
- HDU 2516 取石子游戏 (博弈论)
取石子游戏 Problem Description 1堆石子有n个,两人轮流取.先取者第1次能够取随意多个,但不能所有取完.以后每次取的石子数不能超过上次取子数的2倍.取完者胜.先取者负输出" ...
- 【POJ】1067 取石子游戏(博弈论)
Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后 ...
- vijos 1557:bzoj:1413: [ZJOI2009]取石子游戏
Description 在研究过Nim游戏及各种变种之后,Orez又发现了一种全新的取石子游戏,这个游戏是这样的: 有n堆石子,将这n堆石子摆成一排.游戏由两个人进行,两人轮流操作,每次操作者都可以从 ...
随机推荐
- zookeeper源码(01)集群启动
本文介绍一下zookeeper-3.5.7集群安装. 解压安装 tar zxf apache-zookeeper-3.5.7-bin.tar.gz 创建数据.日志目录: mv apache-zooke ...
- JMS微服务开发示例(六)安全退出进程
默认情况下,如果在linux,需要关闭微服务进程,请务必使用 kill -15 进程id 命令,其他命令可能会直接关闭进程,造成数据丢失. 例如,有个后台任务,执行了一半,这时候进程突然关闭了,会形成 ...
- [转帖]Shell if 条件判断
Shell 语言中的if条件 一.if的基本语法: if [ command ];then 符合该条件执行的语句 elif [ command ];then 符合该条件执行的语句 e ...
- [转帖]TiKV Config Learn the TiKV configuration file
The TiKV configuration file supports more options than command-line parameters. You can find the def ...
- 关于decimal非常浅显的学习与整理
关于decimal非常浅显的学习与整理 背景知识 整数,小数,浮点,定点 整数(Integer)是没有小数部分的数值,可以是正数.负数或零.在计算机中,整数通常以二进制形式存储. 小数(Decimal ...
- [转帖][大数据]ETL之增量数据抽取(CDC)
https://www.cnblogs.com/johnnyzen/p/12781942.html 目录 1 CDC 概念 1.1 定义 1.2 需求背景 1.3 考察指标 2 CDC 常见解决方案 ...
- [转帖]ioping测试
https://www.cnblogs.com/ishmaelwanglin/p/10839702.html 一个实时显示磁盘io延时的工具,以类似ping 的输出一样展示输出结果 常用参数: -c ...
- [转帖]Linux文件夹对比并提取的差分文件技巧-rsync的妙用
https://www.xitongjiaocheng.com/linux/2017/45720.html 需求 最近团队正在开发一个版本对比工具,要求是把A1文件夹与A2对比,将A2中的增量部分 ...
- [转帖]linux,wget 的证书不可信,证书使用不安全的算法签名
centos wget 的证书不可信,证书使用不安全的算法签名 wget wget https://www.php.net/distributions/php-7.4.28.tar.gz 出现错误: ...
- 【杂题,树】【Uoj】Uoj618 【JOISC2021】聚会 2
2023.7.3 Problem Link 给定一棵 \(n\) 个点的树,对于一个点集 \(S\),定义 \(f(u,S)\) 为 \(\min_u \sum_{v\in S} \mathrm{di ...