Paint Chain(博弈论-sg函数)

Paint Chain(博弈论-sg函数)

judge:HDUOJ 3980
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)
source:2011 Multi-University Training Contest 14 - Host by FZU

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
HDUOJ 3980

Input

HDUOJ 3980

Output

HDUOJ 3980

Sample Input

2
3 1
4 2

Sample Output

Case #1: aekdycoin
Case #2: abcdxyzk

题意

有一串项链,项链上有n个珠子。现规定两个人每回合都必须拿走连续的m个珠子,最后不能拿走m个连续珠子的人输。给你n和m,问你谁会赢。

sg函数打表,博弈论没什么好解释的,也解释不清……

参考别人的解释:

一个圆环N个数,每次每个人只能给连续的M个数抹漆,最后不能抹的就算输(大概这个意思啦,英语不好)。。首先第一个人抹了之后就变成直线了。。先手变后手了…
(5,2) +++++之后的状态可以有<–+++><+–++><++–+><+++–>
一个问题的结果是其子问题的结果的亦或。。。
对于一个直线的情况,其子状态有前边空几个那么多的情况。。
比如(5,2) +++++,
当前边空0个时子游戏为(0,2)(3,2)
当前边空1个时子游戏有(1,2)(2,2)
当前边空2个时子游戏有(2,2)(1,2)
当前边空3个时子游戏有(3,2)(0,2)
所以求SG时记忆化递推。。就可以求出(n,m)状态的SG。
————————————————
版权声明:本文为CSDN博主「xtulollipop」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xtulollipop/article/details/51998133

代码
#include <string>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int N = 1e3+5;
const int mod = 1e9+7;
const int maxn = 10005;

int sg[1006];
int vis[1006];
int n, m;

int getsg(int n) {
	if(sg[n] != -1) return sg[n];
	if(n < m) return sg[n] = 0;
	memset(vis, 0, sizeof(vis));
	for(int i = m; i <= n; i++){
		vis[getsg(i - m) ^ getsg(n - i)] = 1;
	}
	int pos = 0;
	while(vis[pos]) pos++;
	sg[n] = pos;
	return pos;
}

int main() {
	//freopen("in.txt", "r", stdin);
	
	int T, ca = 1;
	scanf("%d", &T);
	while(T--){
		scanf("%d%d", &n, &m);
		if(n < m) {
			printf("Case #%d: abcdxyzk\n", ca++);
			continue;
		}
		n -= m;
		memset(sg, -1, sizeof(sg));
		for(int i = 0; i <= n; i++) sg[i] = getsg(i);
		printf("Case #%d: %s\n", ca++, !sg[n] ? "aekdycoin" : "abcdxyzk");
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值