取球游戏(nyoj 518)

24 篇文章 0 订阅

题目:点击打开链接

蓝桥杯的题,寒假的时候看还不会,看了解析也没太理解。这几天基本都在看博弈,就重新看了看这个题。

看了以后第一反应就是用SG函数……用SG函数时间不错,就是比较耗内存。

#include <stdio.h>
#include <string.h>

int sg[10010];
int s[4] = {1, 3, 7, 8};

int getsg(int x)
{
	int i;
	if(sg[x] != -1)
		return sg[x];
	bool hash[1010];//之前hash数组开大了。rt了两次 
	memset(hash, 0, sizeof(hash));
	for(i = 0; i < 4; i++)
	{
		if(x >= s[i])
		{
			sg[x - s[i]] = getsg(x - s[i]);
			hash[sg[x - s[i]]] = 1;
		}
	}
	for(i = 0; i < 1010; i++)
	{
		if(!hash[i])
			break;
	}
	return sg[x] = i;
}

int main (void)
{
	int n;
	memset(sg, -1, sizeof(sg));
	sg[0] = 1;
	sg[1] = 0;
	scanf("%d", &n);
	while(n --)
	{
		int m;
		scanf("%d", &m);
		sg[m] = getsg(m);
		printf("sg = %d\n", sg[m]);
		if(sg[m] == 0)
			printf("0\n");
		else
			printf("1\n");
	}
	return 0;
}


另一种方法:

s[i - 1] && s[i - 3] && s[i - 7] && s[i - 8] == 1 的意思是,如果此结点的后继结点中存在必败态,那么为了让对方输,就要将石子减少到相应的必败态以保证“我”是取胜的。如果所有后继结点都是必胜态,那么不管减少到哪个状态,对方都是赢的,”我”就输了。

#include <stdio.h>

int s[10010] = {-1, 0, 1, 0, 1, 0, 1, 0, 1};

int main (void)
{
	int n, i;
	for(i = 9; i < 10010; i++)
	{
		if(s[i - 1] && s[i - 3] && s[i - 7] && s[i - 8] == 1)
			s[i] = 0;
		else
			s[i] = 1;
	}
	scanf("%d", &n);
	while(n --)
	{
		int m;
		scanf("%d", &m);
		printf("%d\n", s[m]);
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值