HDU 5795 A Simple Nim (博弈) ---2016杭电多校联合第六场
2016-08-04 18:58
267 查看
A Simple Nim
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 79 Accepted Submission(s): 48
[align=left]Problem Description[/align]
Two players take turns picking candies from n heaps,the player who picks the last one will win the game.On each turn they can pick any number of candies which come from the same heap(picking no candy is not allowed).To make the game more interesting,players can separate one heap into three smaller heaps(no empty heaps)instead of the picking operation.Please find out which player will win the game if each of them never make mistakes.
[align=left]Input[/align]
Intput contains multiple test cases. The first line is an integer 1≤T≤100, the number of test cases. Each case begins with an integer n, indicating the number of the heaps, the next line contains N integers s[0],s[1],....,s[n−1], representing heaps with s[0],s[1],...,s[n−1] objects respectively.(1≤n≤106,1≤s[i]≤109)
[align=left]Output[/align]
For each test case,output a line whick contains either"First player wins."or"Second player wins".
[align=left]Sample Input[/align]
2
2
4 4
3
1 2 4
[align=left]Sample Output[/align]
Second player wins.
First player wins.
[align=left]Author[/align]
UESTC
[align=left]Source[/align]
2016 Multi-University Training Contest 6
[align=left]Recommend[/align]
wange2014
题意:给定n堆石子,每次有两种操作,1是从任意一堆中取任意个,2是把一堆分为三堆且这三堆都不为空,问谁能赢。
题解:首先看题目的数据范围是1e9,那么算出每个sg肯定会超时,所以我们想到打表找规律。首先我们暴力打表算出200以内的sg函数值,对于一堆石子来说处理出他的所有后继情况。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int sg[10005]= {0}; bool vis[10005]; int t,cas=1; void get() { memset(sg,0,sizeof(sg)); sg[0]=0; for(int i=1; i<=200; i++) { memset(vis,0,sizeof(vis)); for(int j=1;j<=i;j++) { for(int k=1;j+k<=i;k++) { if(j!=0&&k!=0&&((i-j-k)!=0)) vis[sg[j]^sg[k]^sg[i-j-k]]=1;//操作1 } } for(int j=0;j<i;j++)//操作2 vis[sg[j]]=1; for(int x=0; ; x++) if(!vis[x]) { sg[i]=x; break; } } } int main() { get(); for(int i=1;i<=100;i++) printf("i: %d %d\n",i,sg[i]); return 0; }
运行该代码,我们会得到如下结果:
注意在这个表当中
观察结果我们可以得知,当n为8的倍数时,sg(n)=n+1; 当(n+1)为8的倍数时,sg(n)=n-1; 否则sg(n)=n;
所以我们把sg值异或起来就能判断出谁赢了。
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> using namespace std; int main() { int t; scanf("%d",&t); while(t--) { int n; long long x,ans=0; scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%lld",&x); if(x%8==0) ans=ans^(x-1); else if((x+1)%8==0) ans=ans^(x+1); else ans=ans^x; } if(ans) puts("First player wins."); else puts("Second player wins."); } return 0; }
相关文章推荐
- HDU 5793 A Boring Question (逆元+快速幂+费马小定理) ---2016杭电多校联合第六场
- HDU 5724 Chess (状态压缩sg函数博弈) 2016杭电多校联合第一场
- HDU 5744 Keep On Movin (贪心) 2016杭电多校联合第二场
- HDU 5831 Rikka with Parenthesis II (贪心) -2016杭电多校联合第8场
- HDU 5745 La Vie en rose (DP||模拟) 2016杭电多校联合第二场
- HDU 5762 Teacher Bo (鸽笼原理) 2016杭电多校联合第三场
- HDU 5734 Acperience (公式推导) 2016杭电多校联合第二场
- HDU 5821 Ball (贪心排序) -2016杭电多校联合第8场
- HDU 5821 Ball (贪心排序) -2016杭电多校联合第8场
- 2016多校联合训练赛 第六场1003 A Simple Nim hdu 5795
- HDU 5752 Sqrt Bo (思维题) 2016杭电多校联合第三场
- HDU 5742 It's All In The Mind (贪心) 2016杭电多校联合第二场
- hdu 4664 Triangulation/杭电多校2013第六场1010, SG定理+找规律
- (HDU 5724)2016 Multi-University Training Contest 1 Chess(SG函数、博弈)
- hdu 5798 Stabilization(2016多校第六场1006)
- 2016多校联合训练赛 第三场1010 Rower Bo hdu 5761
- HDU 5723 Abandoned country【2016多校联合】(最小生成树+深搜)
- hdu 5801 Up Sky,Mr.Zhu(2016多校第六场1009) 可持久化字典树
- 2016多校联合训练赛 第四场1001 Another Meaning hdu 5763
- hdu 5754 2016 Multi-University Training Contest 3(各种博弈)