暑假考试题2:Nim游戏 改(博弈论)

题目:

其实就是在nim游戏基础上添加了一次可以不取的机会。

多堆石子可以看成多个游戏,它们起点的sg值异或起来就是整个游戏的sg值,若sg值为1,则先手必胜,为0,则后手必胜。

关键在于怎么求sg值:可以打表找规律->对游戏局面进行动态dfs连边再dfs一遍求sg值(也就是求mex值)

细节:dfs能跑到的范围很小,最多到20(可能还达不到,因为边实在是太多了),所以死循环时不要怀疑是自己打错了,还可能是石子数太大了。

规律:石子数为奇数,mex值为a[i]+1,偶数,mex值为a[i]-1。

打表代码:

#include<bits/stdc++.h>
using namespace std;
#define N 25
#define M 100005
int tong[M][N],mexx[M],head[M],to[M],nex[M],tot=0,val[M],ndnum,fl[M];
void add(int a,int b) { to[++tot]=b; nex[tot]=head[a]; head[a]=tot; }
void dfs(int u)
{
    if(val[u]==0) return ;
    if(fl[u]==0){
        val[++ndnum]=val[u];
        add(u,ndnum); fl[ndnum]=1;
        dfs(ndnum);
    }
    for(int i=0;i<=val[u]-1;i++){
        val[++ndnum]=i;
        add(u,ndnum);
        fl[ndnum]=fl[u];
        dfs(ndnum);
    }
}
void SG(int u)
{
    if(val[u]==0) { mexx[u]=0; return ; }
    for(int i=head[u];i;i=nex[i]){
        int v=to[i];
        SG(v);
        tong[u][mexx[v]]=true;
    }
    for(int i=0;i<=20;i++)
    if(!tong[u][i]) { mexx[u]=i; return ; }
}
int main()
{
    for(int i=1;i<=10;i++){
        int id=++ndnum;
        val[id]=i; fl[id]=0;
        dfs(id);
        SG(id);
        printf("mex:%d %d\n",i,mexx[id]);
    }
}

打表找到规律后的代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
    freopen("nim.in","r",stdin);
    freopen("nim.out","w",stdout);
    int T,n,a;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        scanf("%d",&a);
        if(a&1) a++; else a--;
        ll ans=a;
        for(int i=2;i<=n;i++){
            scanf("%d",&a);
            if(a&1) a++;
            else a--;
            ans^=a;
        }
        if(ans) printf("A\n");
        else printf("B\n");
    }
}
/*
2
2
1 2
2
2 2
*/

原文地址:https://www.cnblogs.com/mowanying/p/11402738.html

时间: 2024-10-31 13:46:01

暑假考试题2:Nim游戏 改(博弈论)的相关文章

[CQOI2013]新Nim游戏(博弈论,线性基)

[CQOI2013]新Nim游戏 题目描述 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴.可以只拿一根,也可以拿走整堆火柴,但不能同时从超过一堆火柴中拿.拿走最后一根火柴的游戏者胜利. 本题的游戏稍微有些不同:在第一个回合中,第一个游戏者可以直接拿走若干个整堆的火柴.可以一堆都不拿,但不可以全部拿走.第二回合也一样,第二个游戏者也有这样一次机会.从第三个回合(又轮到第一个游戏者)开始,规则和Nim游

编程之美----NIM游戏

: 博弈游戏·Nim游戏 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 今天我们要认识一对新朋友,Alice与Bob.Alice与Bob总是在进行各种各样的比试,今天他们在玩一个取石子的游戏.在这个游戏中,Alice和Bob放置了N堆不同的石子,编号1..N,第i堆中有A[i]个石子.每一次行动,Alice和Bob可以选择从一堆石子中取出任意数量的石子.至少取1颗,至多取出这一堆剩下的所有石子.Alice和Bob轮流行动,取走最后一个石子的人获得胜利.假设每一轮游

(转载)Nim游戏博弈(收集完全版)

Nim游戏的概述: 还记得这个游戏吗?给出n列珍珠,两人轮流取珍珠,每次在某一列中取至少1颗珍珠,但不能在两列中取.最后拿光珍珠的人输.后来,在一份资料上看到,这种游戏称为“拈(Nim)”.据说,它源自中国,经由被贩卖到美洲的奴工们外传.辛苦的工人们,在工作闲暇之余,用石头玩游戏以排遣寂寞.后来流传到高级人士,则用便士(Pennies),在酒吧柜台上玩.最有名的玩法,是把十二枚便士放成3.4.5三列,拿光铜板的人赢.后来,大家发现,先取的人只要在3那列里取走2枚,变成了1.4.5,就能稳操胜券了

Nim游戏变种——取纽扣游戏

(2016腾讯实习生校招笔试题)Calvin和David正在玩取纽扣游戏,桌上一共有16个纽扣,两人轮流来取纽扣,每人每次可以选择取1个或3个或6个(不允许不取),谁取完最后的纽扣谁赢.Cavin和David都非常想赢得这个游戏,如果Cavin可以先取,Cavin的必胜策略下第一步应该取 A.1个 B.3个 C.6个 D.Cavin没有必胜策略 解析:这道题是Nim游戏的变种,Nim游戏是博弈论中最经典的模型(之一). 根据博弈论的性质:对于巴什博弈,存在必胜点和必败点,是指在当前这个点上的先手

(博弈论) 51NOD 1069 Nim游戏

有N堆石子.A B两个人轮流拿,A先拿.每次只能从一堆中取若干个,可将一堆全取走,但不可不取,拿到最后1颗石子的人获胜.假设A B都非常聪明,拿石子的过程中不会出现失误.给出N及每堆石子的数量,问最后谁能赢得比赛. 例如:3堆石子,每堆1颗.A拿1颗,B拿1颗,此时还剩1堆,所以A可以拿到最后1颗石子. Input 第1行:一个数N,表示有N堆石子.(1 <= N <= 1000) 第2 - N + 1行:N堆石子的数量.(1 <= A[i] <= 10^9) Output 如果A

hdu 1849Rabbit and Grass(博弈论 一维nim游戏)

Rabbit and Grass Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3058    Accepted Submission(s): 2261 Problem Description 大学时光是浪漫的,女生是浪漫的,圣诞更是浪漫的,但是Rabbit和Grass这两个大学女生在今年的圣诞节却表现得一点都不浪漫:不去逛商场,不去逛

BZOJ_1022_[SHOI2008]_小约翰的游戏John_(博弈论_反Nim游戏)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1022 反Nim游戏裸题.详见论文<组合游戏略述——浅谈SG游戏的若干拓展及变形>. 分析 1 #include <bits/stdc++.h> 2 using namespace std; 3 inline int read(int &x){x=0;int k=1;char c;for(c=getchar();c<'0'||c>'9';c=getchar()

BZOJ3105: [cqoi2013]新Nim游戏 博弈论+线性基

一个原来写的题. 既然最后是nim游戏,且玩家是先手,则希望第二回合结束后是一个异或和不为0的局面,这样才能必胜. 所以思考一下我们要在第一回合留下线性基 然后就是求线性基,因为要取走的最少,所以排一下序,从大到小求. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 #include<cmath> 6 #include<algor

Nim 游戏、SG 函数、游戏的和

Nim游戏 Nim游戏定义 Nim游戏是组合游戏(Combinatorial Games)的一种,准确来说,属于"Impartial Combinatorial Games"(以下简称ICG).满足以下条件的游戏是ICG(可能不太严谨):1.有两名选手:2.两名选手交替对游戏进行移动(move),每次一步,选手可以在(一般而言)有限的合法移动集合中任选一种进行移动:3.对于游戏的任何一种可能的局面,合法的移动集合只取决于这个局面本身,不取决于轮到哪名选手操作.以前的任何操作.骰子的点数