题目链接

题目

题目描述

有一种有趣的游戏,玩法如下:

玩家:2人;

道具:N堆石子,每堆石子的数量分别为 \(X_1,X_2,...,X_n\) ​;

规则:

  1. ​ 游戏双方轮流取石子;
  2. ​ 每人每次选一堆石子,并从中取走若干颗石子(至少取1颗);
  3. ​ 所有石子被取完,则游戏结束;
  4. ​ 如果轮到某人取时已没有石子可取,那此人算负。

假如两个游戏玩家都非常聪明,问谁胜谁负?

输入描述

第一行,一个整数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\) 时为必败态,否则为必胜态(这里只是假设,字面上的意义还需要证明),考虑证明:

  1. 游戏终止状态为必败态:

    终止状态为全 \(0\) ,满足我们的假设。

  2. 必败态只能转到必胜态:

    假设存在合法操作使得必败态转到必败态,那么存在一个石子堆被改变了,不妨设它新的数量为 \(a_i'\) ,设其他没有改变的石子堆的异或和为 \(sum\) ,我们可以得到 \(sum \oplus a_i' = sum \oplus a_i = 0\) ,最后 \(a_i' = a_i\) 矛盾。

    因此必败态只能转到必胜态。

  3. 必胜态可以转到必败态:

    我们设当前异或和为 \(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的更多相关文章

  1. Games:取石子游戏(POJ 1067)

    取石子游戏 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 37662   Accepted: 12594 Descripti ...

  2. HDU 2516 取石子游戏(斐波那契博弈)

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

  3. hdu 1527 取石子游戏(Wythoff Game)

    题意:Wythoff Game 思路:Wythoff Game #include<iostream> #include<stdio.h> #include<math.h& ...

  4. HDU 2516 取石子游戏(FIB博弈)

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

  5. 1874: [BeiJing2009 WinterCamp]取石子游戏 - BZOJ

    Description小H和小Z正在玩一个取石子游戏. 取石子游戏的规则是这样的,每个人每次可以从一堆石子中取出若干个石子,每次取石子的个数有限制,谁不能取石子时就会输掉游戏. 小H先进行操作,他想问 ...

  6. HDU-1527 取石子游戏

    http://acm.hdu.edu.cn/showproblem.php?pid=1527 交换  :可实现. if( n < m ) { n^=m; m^=n; n^=m; } (三)尼姆博 ...

  7. bzoj 1874 取石子游戏 题解 &amp; SG函数初探

    [原题] 1874: [BeiJing2009 WinterCamp]取石子游戏 Time Limit: 5 Sec  Memory Limit: 162 MB Submit: 334  Solved ...

  8. HDU 2516 取石子游戏 (博弈论)

    取石子游戏 Problem Description 1堆石子有n个,两人轮流取.先取者第1次能够取随意多个,但不能所有取完.以后每次取的石子数不能超过上次取子数的2倍.取完者胜.先取者负输出" ...

  9. 【POJ】1067 取石子游戏(博弈论)

    Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后 ...

  10. vijos 1557:bzoj:1413: [ZJOI2009]取石子游戏

    Description 在研究过Nim游戏及各种变种之后,Orez又发现了一种全新的取石子游戏,这个游戏是这样的: 有n堆石子,将这n堆石子摆成一排.游戏由两个人进行,两人轮流操作,每次操作者都可以从 ...

随机推荐

  1. VUEX 使用学习六 : modules

    转载请注明出处: 当Store中存放了非常多非常大的共享数据对象时,应用会变的非常的复杂,Store对象也会非常臃肿,所以Vuex提供了一个Module模块来分隔Store.通过对Vuex中的Stor ...

  2. python3之lambda表达式

    技术背景 lambda表达式本身是一个非常基础的python函数语法,其基本功能跟使用def所定义的python函数是一样的,只是lambda表达式基本在一行以内就完整的表达了整个函数的运算逻辑.这里 ...

  3. 浏览器兼容 : IE 5 到 IE 9

    <!--[if IE]> <link href="ie.css" rel="stylesheet"> <![endif]--> ...

  4. C++17 解构绑定

    在python中,加入我们有一个函数返回了两个数值,如: def getData(x, y): return x,y 那么我们在使用这个函数时只需要使用两个新变量去接收函数返回值就可以: a,b = ...

  5. [转帖]深度硬核文:Nginx的301重定向处理过程分析

    https://zhuanlan.zhihu.com/p/84539204 本文首发于公众号:js-mindmap 一,序言 "晚上九点,办公室里烟雾缭绕,工作进度依然没有什么进展.王二胖打 ...

  6. [转帖]高性能分布式对象存储——MinIO实战操作(MinIO扩容)

    https://juejin.cn/post/7132852449244610574 一.前言 MinIO的基础概念和环境部署可以参考我之前的文章:高性能分布式对象存储--MinIO(环境部署) 二. ...

  7. Kafka学习之四_Grafana监控相关的学习

    Kafka学习之四_Grafana监控相关的学习 背景 想一并学习一下kafaka的监控. 又重新开始学习grafana了: 下载地址: https://grafana.com/grafana/dow ...

  8. [转帖]kafka压测多维度分析实战

    设置虚拟机不同的带宽来进行模拟压测 ---------kafka数据压测-------------------1.公司生产kafka集群硬盘:单台500G.共3台.日志保留7天.         1. ...

  9. 【转帖】JVM 内存模型与垃圾回收

    文章目录 1. JVM内存模型 1.1. 程序计数器 (线程私有) 1.2. Java 虚拟机栈 (线程私有) 1.3. 本地方法栈 (线程私有) 1.4. Java 堆 (线程共享) 1.5. 方法 ...

  10. [转帖]Unixbench的使用(综合性能测试、2D测试)和问题解决(跑不出多线程分数,调不出窗口,报错等)

    一.Unixbench简介 Unixbench一个基于系统的基准测试工具,不单纯是CPU 内存 或者磁盘测试工具.测试结果不仅仅取决于硬件,也取决于系统.开发库.甚至是编译器.Unixbench是一个 ...