HDU 1907 Nim博弈变形

1、HDU 1907  

2、题意:n堆糖,两人轮流,每次从任意一堆中至少取一个,最后取光者输

3、总结:有点变形的Nim,还是不太明白,盗用一下学长的分析吧 传送门 

分析:经典的Nim博弈的一点变形。设糖果数为1的叫孤独堆,糖果数大于1的叫充裕堆,设状态S0:a1^a2^..an!=0&&充裕堆=0,则先手必败(奇数个为1的堆,先手必败)。S1:充裕堆=1,则先手必胜(若剩下的n-1个孤独堆个数为奇数个,那么将那个充裕堆全部拿掉,否则将那个充裕堆拿得只剩一个,这样的话先手必胜)。T0:a1^a2^..an=0&&充裕堆=0,先手必胜(只有偶数个孤独堆,先手必胜)。S2:a1^a2^..an!=0&&充裕堆>=2。T2:a1^a2^..an=0&&充裕堆>=2。这样的话我们用S0,S1,S2,T0,T2将所有状态全部表示出来了,并且S0先手必败,S1、T0先手必胜,那么我们只需要对S2和T2的状态进行分析就行了。(a)S2可以取一次变为T2。(b)T2取一次可变为S2或者S1。因为S1是先手必胜态,那么根据a,b这两个转换规则,我们就能得知S2也是先手必胜,T2是先手必败。

#include<bits/stdc++.h>
#define F(i,a,b) for (int i=a;i<b;i++)
#define FF(i,a,b) for (int i=a;i<=b;i++)
#define mes(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int N=10010;

int main()
{
    int T,n,a[100];
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&n);
        int ans=0,flag=0;
        F(i,0,n) {
            scanf("%d",&a[i]);
            ans^=a[i];
            if(a[i]!=1) flag=1;     //全部为1就要特判
        }
        if(flag) {
            if(!ans) puts("Brother");
            else puts("John");
        } else {
            if(ans^1==1) puts("John");
            else puts("Brother");
        }
    }

    return 0;
}

时间: 2024-10-13 15:38:20

HDU 1907 Nim博弈变形的相关文章

hdu 1907(Nim博弈)

John Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 4407    Accepted Submission(s): 2520 Problem Description Little John is playing very funny game with his younger brother. There is one big bo

HDU 3032 (Nim博弈变形) Nim or not Nim?

博弈的题目,打表找规律还是相当有用的一个技巧. 这个游戏在原始的Nim游戏基础上又新加了一个操作,就是游戏者可以将一堆分成两堆. 这个SG函数值是多少并不明显,还是用记忆花搜索的方式打个表,规律就相当显然了. 1 #include <cstdio> 2 #include <cstring> 3 4 const int maxn = 100; 5 int sg[maxn * 2]; 6 bool vis[maxn * 2]; 7 8 int mex(int v) 9 { 10 if(

hdu 5011 (nim博弈模版)

//nim博弈 //有n堆石头,两人轮流每次从一堆中拿至少1,之多全部的石头,没有石头可拿为lose //判断先手是win还是lose # include <stdio.h> # include <algorithm> # include <string.h> using namespace std; int main() { int n,i; __int64 a,sum; while(~scanf("%d",&n)) { sum=0; fo

poj3480 John (nim博弈变形--SJ定理)

John Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2940   Accepted: 1432 Description Little John is playing very funny game with his younger brother. There is one big box filled with M&Ms of different colors. At first John has to eat s

hdu 1730 Nim博弈

Tom和Jerry正在玩一种Northcott游戏,可是Tom老是输,因此他怀疑这个游戏是不是有某种必胜策略,郁闷的Tom现在向你求救了,你能帮帮他么? 游戏规则是这样的:  如图所示,游戏在一个n行m列(1 ≤ n ≤ 1000且2 ≤ m ≤ 100)的棋盘上进行,每行有一个黑子(黑方)和一个白子(白方).执黑的一方先行,每次玩家可以移动己方的任何一枚棋子到同一行的任何一个空格上,当然这过程中不许越过该行的敌方棋子.双方轮流移动,直到某一方无法行动为止,移动最后一步的玩家获胜.Tom总是先下

hdu 1730 Northcott Game (nim博弈变形)

# include <algorithm> # include <stdio.h> # include <string.h> # include <math.h> # include <iostream> using namespace std; int main() { int n,m,i,a,b,cot; while(~scanf("%d%d",&n,&m)) { cot=0; for(i=0; i<

hdu 1536 NIM博弈 (模板)

推荐文章 博弈论初步:http://www.cnblogs.com/Knuth/archive/2009/09/05/1561002.html 博弈解决思想:http://www.cnblogs.com/Knuth/archive/2009/09/05/1561005.html NIM游戏:http://www.cnblogs.com/Knuth/archive/2009/09/05/1561008.html 关于SG函数:http://www.cnblogs.com/Knuth/archive

HDU 1850 (Nim博弈 取胜方案数) Being a Good Boy in Spring Festival

考虑到Bouton定理的证明过程,设n个数的Nim和(异或和)为X,其最高位的1在第k位,那么n个数中一定有个y的第k为也是个1. 将y的数量变为X xor y,那么n的数的Nim和为0,便转为先手必败局面. 所以先手有多少种取法,就看n个数里面有多少个y,满足二进制的第k为是个1. 1 #include <cstdio> 2 3 const int maxh = 20; 4 const int maxn = 100 + 10; 5 int a[maxn]; 6 7 int main() 8

HDU 2509 Nim博弈

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2509 题意:有N堆,谁最后拿谁输. 关键:判断孤单堆. 1 #include<cstdio> 2 #define ll long long 3 using namespace std; 4 5 int main() 6 { 7 int n; 8 while( ~scanf("%d",&n)){ 9 int temp,ans=0,flag=0; 10 for(int i=