[hdu-5795]A Simple Nim 博弈 尼姆博弈 SG函数打表找规律

【题目】题目链接

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.

InputIntput contains multiple test cases. The first line is an integer 1≤T≤1001≤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]s[0],s[1],....,s[n−1], representing heaps with s[0],s[1],...,s[n−1]s[0],s[1],...,s[n−1] objects respectively.(1≤n≤106,1≤s[i]≤109)(1≤n≤106,1≤s[i]≤109)OutputFor each test case,output a line whick contains either"First player wins."or"Second player wins".

Sample Input

2
2
4 4
3
1 2 4

Sample Output

Second player wins.
First player wins

【题意】类似尼姆游戏(n堆石子,两人轮流从一堆中取出若干石子),加入了一个操作:可以  不取走石子而是把石子分为三堆(每堆不可为空)恰好将所有石子取完的一方胜

【题解】普通尼姆博弈 n堆石子的后继状态为0~n-1,所有堆的石子数异或和为0时为必败状态。而拆分操作,例如将10拆为2 3 5,实际上相当于后继状态 2^3^5=4,把7拆为1 2 3相当于后继状态1^2^3=7  7的所有后继状态为  0  1 2 3 4 5 6 1^1^5 1^2^4 1^3^3 2^2^3 然后用SG函数的性质打表就可以了(SG(X)=后继状态没有出现的最小自然数)观察可以出 SG(X)=X+1   (X%8==7)SG(X)=X-1   (X%8==0)SG(X)=X      其他

【SG定理】P点:必败点,某玩家位于此点,只要对方无失误,则必败N点:必胜点,某玩家位于此点,只要自己无失误,则必胜定理:1.所有总结点都是P点。2.无论任何操作,必败点P只能进入必胜点N。3.从任何必胜点N,至少有一种方式进入必败点P。

Mex运算:首先定义mex(minimal excludant)运算,这是施加于一个集合的运算,表示最小的不属于这个集合的非负整数。即:mex(S)=min{x},x∈N,x∉S例如mex{0,1,2,4}=3、mex{2,3,5}=0、mex{}=0。

SG函数:

定理1:

1.有向图游戏的某个局面必胜,当且仅当该局面对应的节点的SG函数值大于0。

2.有向图游戏的某个局面必败,当且仅当该局面对应的节点的SG函数值等于0。

定理2:

多个有向图游戏组成的游戏{Gi,n}必胜,当且仅当有向图游戏的和SG函数值不为0.

【打表代码】

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int g[1010];
 4 void init() {
 5     memset(g, -1, sizeof(g));
 6 }
 7 int getSG(int x) {
 8     if(g[x] != -1) return g[x];
 9     if(x == 0) return 0;
10     if(x == 1) return 1;
11     if(x == 2) return 2;
12     int vis[110];
13     memset(vis, 0, sizeof(vis));
14     for(int i = 1; i < x; i++) {
15         int t = 0;
16         int a = getSG(i);
17         vis[a] = 1;
18         for(int j = 1; j < x - i; j++) {
19             int b = getSG(j);
20             int c = getSG(x - i - j);
21             vis[a^b^c] = 1;
22         }
23     }
24     vis[0] = 1;
25     for(int i = 0; ; i++) if(!vis[i])
26         return g[x] = i;
27 }
28 int main() {
29     int n;
30     init();
31     for(int i = 1; i <= 100; i++) {
32         g[i] = getSG(i);
33         printf("%d %d %d\n", i, i % 8, g[i]);
34     }
35 }

【AC代码】

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int getsg(int x){
 4     if(x%8==0)return x-1;
 5     if(x%8==7)return x+1;
 6     return x;
 7 }
 8 int main(){
 9     int t,n,c,ans;
10     scanf("%d",&t);
11     while(t--){
12         ans=0;
13         scanf("%d",&n);
14         for(int i=1;i<=n;i++){
15             scanf("%d",&c);
16             ans^=getsg(c);
17         }
18         if(ans)printf("First player wins.\n");
19         else printf("Second player wins.\n");
20     }
21     return 0;
22 }

原文地址:https://www.cnblogs.com/conver/p/12200745.html

时间: 2024-08-03 19:16:27

[hdu-5795]A Simple Nim 博弈 尼姆博弈 SG函数打表找规律的相关文章

hdu 5795 A Simple Nim 博弈sg函数

A Simple Nim Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Description 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 an

?HDU 5795 A Simple Nim(简单Nim)

HDU 5795 A Simple Nim(简单Nim) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)   Problem Description - 题目描述 Two players take turns picking candies from n heaps,the player who picks the last one will win the game.On e

Nim or not Nim? hdu3032 SG值打表找规律

Nim or not Nim? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 858    Accepted Submission(s): 412 Problem Description Nim is a two-player mathematic game of strategy in which players take turns

HDU 5795 A Simple Nim (博弈) ---2016杭电多校联合第六场

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 Problem Description Two players take turns picking candies from n heaps,the player who picks the las

hdu 5795 A Simple Nim (sg 博弈)

官方题解: A Simple Nim sg[0]=0 当x=8k+7时sg[x]=8k+8, 当x=8k+8时sg[x]=8k+7, 其余时候sg[x]=x:(k>=0) 打表找规律可得,数学归纳法可证. 具体的打表放在了代码里面 ,详见init函数 /*by*/ #include <iostream> #include <algorithm> #include <cstdio> #include <cstring> using namespace s

POJ2975 Nim 博弈论 尼姆博弈

http://poj.org/problem?id=2975 题目始终是ac的最大阻碍. 问只取一堆有多少方案可以使当前局面为先手必败. 显然由尼姆博弈的性质可以知道需要取石子使所有堆石子数异或和为0,那么将某一堆a个石子变为a^异或和即可. a1^a2^a3^...^an=y; a1^a2^a3^...^an^y=0; 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<

HDU 5795 A Simple Nim 打表求SG函数的规律

A Simple Nim Problem Description 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).T

hdu 1850 Being a Good Boy in Spring Festival (尼姆博弈)

Being a Good Boy in Spring Festival Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4658    Accepted Submission(s): 2781 Problem Description 一年在外 父母时刻牵挂春节回家 你能做几天好孩子吗寒假里尝试做做下面的事情吧 陪妈妈逛一次菜场悄悄给爸爸买

HDUOJ--------A simple stone game(尼姆博弈扩展)(2008北京现场赛A题)

A simple stone game                                                                                                       Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)