HDU 3980 Paint Chain(博弈 SG)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3980

Problem Description

Aekdycoin and abcdxyzk are playing a game. They get a circle chain with some beads. Initially none of the beads is painted. They take turns to paint the chain. In Each turn one player must paint a unpainted beads. Whoever is unable to paint in his turn lose
the game. Aekdycoin will take the first move.

Now, they thought this game is too simple, and they want to change some rules. In each turn one player must select a certain number of consecutive unpainted beads to paint. The other rules is The same as the original. Who will win under the rules ?You may assume
that both of them are so clever.

Input

First line contains T, the number of test cases. Following T line contain 2 integer N, M, indicate the chain has N beads, and each turn one player must paint M consecutive beads. (1 <= N, M <= 1000)

Output

For each case, print "Case #idx: " first where idx is the case number start from 1, and the name of the winner.

Sample Input

2
3 1
4 2

Sample Output

Case #1: aekdycoin
Case #2: abcdxyzk

PS:http://blog.csdn.net/zhjchengfeng5/article/details/8214768

题意

两个人在一个由 n 个玻璃珠组成的一个圆环上玩涂色游戏,游戏的规则是:

1、每人一轮,每轮选择一个长度为 m 的连续的、没有涂过色的玻璃珠串涂色

2、不能涂色的那个人输掉游戏

做法分析

算是比较裸的 SG 函数的应用吧,主要是刚才突然对 博弈 突然来兴趣了,于是就捡了篇论文看看,然后百度了一道水题练练手。。。

可以肯定的是,第一个人涂色之后就把环变成了一个长度为 n-m 的链了,那么我们就可以这样划分阶段了:每轮从一些线段中选择一个,并且把那条线段分成 x, m, len-x-m 的三个部分,其中 len 表示线段原来的长度,m 表示的是已经涂色了,那么这个长为 len 的线段能够得到的子状态最多有
len-m+1 个(其实由对称性可知实际的状态数只是这里的一半),变成了两个长度为 x 和 len-x-m 子游戏,由 SG 定理,SG(len)=SG(x)^SG(len-x-m) 而再由 SG 函数的定义式 SG[u]=mex(seg[v]) 其中,状态 u 可以直接得到状态 v,再加上一个记忆化的小优化,AC了。。。

代码如下:

#include <cstdio>
#include <cstring>
int SG[1056];
int vis[1056];
int n, m;
int get_SG()
{
    memset(SG,0,sizeof(SG));
    SG[m] = 1;
    for(int i = m+1; i <= n; i++)//get Sprague-Grundy value;
    {
        memset(vis,0,sizeof(vis));
        for(int j = 0; j < i-m; j++)
        {
            vis[SG[j]^SG[i-m-j]] = 1;
        }
        for(int j = 0; ; j++)//求mes{}中未出现的最小的非负整数
        {
            if(!vis[j])
            {
                SG[i] = j;
                break;
            }
        }
    }
    return SG[n-m];
}
int main ()
{
    int t;
    int cas = 0;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        printf("Case #%d: ",++cas);
        if(get_SG() || n < m)
            printf("abcdxyzk\n");
        else
            printf("aekdycoin\n");
    }
    return 0;
}
时间: 2024-08-01 10:46:50

HDU 3980 Paint Chain(博弈 SG)的相关文章

HDU 3980 Paint Chain(SG函数)

Problem Description: Aekdycoin and abcdxyzk are playing a game. They get a circle chain with some beads. Initially none of the beads is painted. They take turns to paint the chain. In Each turn one player must paint a unpainted beads. Whoever is unab

hdu 3980 Paint Chain sg函数

题目链接 给一个长度为n的环, 两个人轮流涂色, 每次涂m个连续的, 无法继续涂了就输. 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define pb(x) push_back(x) 4 #define ll long long 5 #define mk(x, y) make_pair(x, y) 6 #define lson l, m, rt<<1 7 #define mem(a) memset(a, 0, sizeo

hdu 3032(博弈sg函数)

题意:与原来基本的尼姆博弈不同的是,可以将一堆石子分成两堆石子也算一步操作,其它的都是一样的. 分析:由于石子的堆数和每一堆石子的数量都很大,所以肯定不能用搜索去求sg函数,现在我们只能通过找规律的办法求得sg的规律. 通过打表找规律可以得到如下规律:if(x%4==0) sg[x]=x-1; if(x%4==1||x%4==2) sg[x]=x; if(x%4==3) sg[x] = x+1. 打表代码: #include<iostream> #include<cstdio> #

(博弈 sg入门)kiki&#39;s game -- hdu -- 2147

链接: http://acm.hdu.edu.cn/showproblem.php?pid=2147 题意: 在一个n*m的棋盘上,从  (1,m),即右上角开始向左下角走. 下棋者只能往左边(left),左下面(left-underneath),下面(underneath),这三个方格下棋. 最后不能移动的人算输 思路: 手动可以画出必胜态以及必败态的图 可以很容易 找出规律 (1) 所有终结点是必败点(P点): (2)从任何必胜点(N点)操作,至少有一种方法可以进入必败点(P点): (3)无

HDU 3537 Daizhenyang&#39;s Coin(博弈-sg)

Daizhenyang's Coin Problem Description We know that Daizhenyang is chasing a girlfriend. As we all know, whenever you chase a beautiful girl, there'll always be an opponent, or a rival. In order to take one step ahead in this chasing process, Daizhen

HDU 3544 (不平等博弈) Alice&#39;s Game

切巧克力的游戏,想得还是不是太明白. 后者会尽量选前着切后其中小的一块来切,那么先手须尽量取中间来切. So?题解都是这么一句话,不知道是真懂了还是从别人那抄过来的. 后来找到一个官方题解,分析得比较认真,但我这智商还是没懂太多,QAQ 本题我抄袭自<Winning Ways for your Mathematical Plays> ,一本关于游戏论的科普类图书.这题是一个组合游戏,但是并不是一个对等的组合游戏,所以试图使用 SG 函数相关知识解答是会面临巨大的挑战的. 书中本题的做法描述得十

hdu 5293 Tree chain problem(树链剖分+树形dp)

题目链接:hdu 5293 Tree chain problem 维护dp[u], sum[u],dp[u]表示以u为根节点的子树的最优值.sum[u]表示以u节点的所有子节点的dp[v]之和.对于边a,b,w,在LCA(a,b)节点的时候进行考虑.dp[u] = min{dp[u], Sum(a,b) - Dp(a,b) + sum[u] | (ab链上的点,不包括u } #pragma comment(linker, "/STACK:1024000000,1024000000")

Treblecross 博弈SG值

Treblecross is a two player game where the goal is to get three X in a row on a one-dimensional board. At the start of the game all cells in the board are empty. In each turn a player puts an X in an empty cell, and if the move results three X next t

UVA 10561 - Treblecross(博弈SG函数)

UVA 10561 - Treblecross 题目链接 题意:给定一个串,上面有'X'和'.',可以在'.'的位置放X,谁先放出3个'X'就赢了,求先手必胜的策略 思路:SG函数,每个串要是上面有一个X,周围的4个位置就是禁区了(放下去必败),所以可以以X分为几个子游戏去求SG函数的异或和进行判断,至于求策略,就是枚举每个位置就可以了 代码: #include <stdio.h> #include <string.h> #include <algorithm> usi