uva_10404-Bachet's Game

/**博弈题。。这种题目的特点就是——想到方法后很简单,想不到
 *就做不出了。。开始想穷举法列出所有结果,后来发现数据量太大
 *行不通,后来看了看博弈相关东西,突然灵光一闪,想到只考虑当前
 *步,把总数为1~count时先手的输赢标记起来,方程为:
 * 	if(i-a[i] == 0 || !num[i-a[i]](i-a[i]>0)) 先手赢
 *就是刚好一次可以移动完,或者移动一次后,对手必输
 */
#include <cstdio>
#include <cstring>
using namespace std;

#define MAX 12
#define MAXC 121

int a[MAX];
int num[MAXC];


void move_stones(int count, int type){
	for(int i = 1; i <= count; i ++){
		for(int j = 0; j < type; j ++){
			if( i - a[j] > 0 && !num[i-a[j]] ){
				num[i] = 1;
				break;
			}else if( i - a[j] == 0 ){
				num[i] = 1;
				break;
			}
		}
	}
	if( num[count] )
		printf("Stan wins\n");
	else
		printf("Ollie wins\n");
}

int main(int argc, char const *argv[])
{
#ifndef ONLINE_JUDGE
		freopen("test.in", "r", stdin);
#endif
	int count, type;
	while( ~scanf("%d", &count) ){
		memset(num, 0, sizeof(num));
		scanf("%d", &type);
		for(int i = 0; i < type; i ++)
			scanf("%d", &a[i]);
		move_stones(count, type);
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值