拿火柴游戏

题目

桌子上有一堆火柴,游戏开始时共有n根火柴,两个玩家轮流拿走1、2、3、4根火柴(选择一种方案拿),拿走最后一根火柴的玩家为获胜方。请问先走的玩家设计一个制胜的策略(如果该策略存在)

思路

若桌子上只有只有1-4根火柴,那么先手必赢;
若桌子上只有5根火柴,那么无论先手拿几根都必输;

也就是意味着先手若要赢,那么快拿到最后的时候,要出现这样一种情况:先手一拿完,巧好剩5根,这才能保证先手必赢;

那么问题就成了怎么出现刚才说的那种情况,其实只需重复一下上面的过程:
若桌子上只有只有6-9根火柴,那么先手可以保证这堆火柴巧好剩5根,回到上面,先手必赢;
若桌子上只有10根火柴,那么无论先手拿几根都必输;

所以,大家应该已经看出规律了,如果火柴数一开始就是5的整数倍,那么先手是没有必赢策略的(后手倒有),只有火柴数一开始就不是5的整数倍,那么先手只需要拿掉几根火柴,使剩余的火柴数是5的整数倍,就可以保证必赢;

然后有人可能会说,看是看懂了,问题是咋想到的了,emmm,我只能说我是根据化繁为简的原则,一开始考虑的火柴数先化到最简单的情形,然后逐步加深。

对于可能有些题目允许拿火柴的数量不一样,可自行调整修改。

代码

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

using namespace std;

int main(){
	srand(time(NULL));//随机种子 	
	printf("输入总得火柴数:");
	int n;//火柴数
	scanf("%d", &n);
	if(n%5 == 0){
		printf("先走玩家无法必赢");
	}
	else{
 		printf("先走玩家可以必赢,下面是必赢策略:\n");
 		int m=n;
 		while(m>0){
  			printf("先手拿:%d\n", m%5);
  			m -= (m%5); 
  			if(m>0){//判断后手是否还有火柴可以拿 
 			int temp = rand()%4 + 1;//后手随机拿1-4根火柴   
			printf("后手拿:%d\n", temp);	
			m -= temp;
		}
  	 }
   return 0; 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值