POJ 2975 Nim(博弈论)
2015-09-03 08:52
375 查看
Description
有n堆石子,每堆石子有ai个,Alice和Bob轮流取,一次只能从一堆中取,可以取任意个,不能不取,谁没得取谁输,问先手有多少种必胜策略(Alice和Bob都足够机智)
Input
多组输入,每组用例占一行,每组用例首先输入石子堆数n,之后输入n个整数表示每堆石子数量,以n=0结束输入
Output
对于每组用例,输出先手必赢策略的种数
Sample Input
3
7 11 13
2
1000000000 1000000000
0
Sample Output
3
0
Solution
首先我们知道经典Nim游戏先手赢的重要条件是每堆石子的数量异或和ans不为0,而如果先手赢则第一步必须将此必胜态转化为必败态,即先手取完一次后所有石子的异或和变成0,设先手首先取x个第i堆石子时是一种必胜策略,设剩余石子堆数量异或和为rest,那么则有a[i]^rest=ans,(a[i]-x)^rest=0,轻易得到x=a[i]-a[i]^ans,显然x>0,即只要a[i]^ans
有n堆石子,每堆石子有ai个,Alice和Bob轮流取,一次只能从一堆中取,可以取任意个,不能不取,谁没得取谁输,问先手有多少种必胜策略(Alice和Bob都足够机智)
Input
多组输入,每组用例占一行,每组用例首先输入石子堆数n,之后输入n个整数表示每堆石子数量,以n=0结束输入
Output
对于每组用例,输出先手必赢策略的种数
Sample Input
3
7 11 13
2
1000000000 1000000000
0
Sample Output
3
0
Solution
首先我们知道经典Nim游戏先手赢的重要条件是每堆石子的数量异或和ans不为0,而如果先手赢则第一步必须将此必胜态转化为必败态,即先手取完一次后所有石子的异或和变成0,设先手首先取x个第i堆石子时是一种必胜策略,设剩余石子堆数量异或和为rest,那么则有a[i]^rest=ans,(a[i]-x)^rest=0,轻易得到x=a[i]-a[i]^ans,显然x>0,即只要a[i]^ans
#include<iostream> #include<cstdio> using namespace std; int main() { int n; while(scanf("%d",&n),n) { int ans=0; int a[1111]; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); ans=ans^a[i]; } int num=0; for(int i=1;i<=n;i++) if((ans^a[i])<a[i]) num++; printf("%d\n",num); } return 0; }
相关文章推荐
- POJ 2234 Matches Game(博弈论)
- 面试之线程篇
- Linux网络管理工具总结
- 7.1Android服务绑定
- TQ2440 学习笔记—— 15、基础知识小结【汇编、vi】
- sqlite3使用
- expdp\impdp及exp\imp
- php大力力 [044节] PHP的POST语句一定要大写!!if(!empty($_POST['id'])) {
- HDOJ 5424 Rikka with Graph II 暴力dfs
- android 内存管理
- Unable to execute dex: Multiple dex files define
- rman备份和expdp备份的区别
- 在游历中长见识
- 监控数据备份恢复完成进度(EXPDP/IMPDP/RMAN)
- [转] IaaS 、PaaS、SaaS科普
- 【OpenCV】SURF的使用
- Kafka设计解析(三)- Kafka High Availability (下)
- POJ 3372 Candy Distribution(数论)
- Android的内存机制和常见泄漏情形
- POJ 2594 Treasure Exploration(最小路径覆盖-hungary+Floyd)