取石头游戏

取石头游戏

两个足够聪明的人玩轮流取石头的游戏,谁取到最后一个石头谁就赢了,他们一次只能取1个、3个、7个或8个石头,写一程序判断n个石头时先取的人是输还是赢。

输入格式:
一个整数n,其值不超过10000000。

输出格式:
如果先取的人赢,请以单独一行输出1,否则输出0。

**输入样例:**
这里是3组输入。

1
10
300
**输出样例:**
上面3组数据对应的输出分别如下:

1
1
0

本题非常巧妙,我们可以先举几个例子来叙述本题.
如果有一个石子,第一个人直接拿一个,那么他就赢了,如果两个,第一个人只能拿一个,剩下的那个就是第二个人的,所以第二个人赢,3个的话第一个人依然可以全部拿完,四个的话第一个人拿一个,那么第二个人就会非常机智的拿走1个,这样就剩下了两个,就回归到了两个的情形,显然第二个人这样做他就赢了,如果第一个人拿走3个,那么依然是第二个人赢,说道这里大家应该就已经明白了这道题目的意思了,就是两个人分别发挥出250的智商,想尽方法不让剩下的那个人赢.
所以,我先给出我第一次时的代码,非常容易理解,采用的思路就是从一个石头到n个石头去试,如果第i-1或者i-3或者i-7或者i-8中有一个是第1个人输,那么第一个人就可以拿剩下到对应的数目,这样的话第二个人再拿的时候就相当于是原来的第一个人,所以他就必输了.
内存超限代码如下:

#include<iostream>
using namespace std;
bool dp[10000005];
int main() {
	int n;
	dp[1]=true;
	dp[3]=true;
	dp[5]=true;
	dp[7]=true;
	dp[8]=true;
	cin>>n;
	if(n<=8)cout<<dp[n];
	else {
		for(int i=9; i<=n; i++) {
			if(dp[i-1]==false)dp[i]=true;
			else if(dp[i-3]==false)dp[i]=true;
			else if(dp[i-7]==false)dp[i]=true;
			else if(dp[i-8]==false)dp[i]=true;
			else dp[i]=false;
		}
		cout<<dp[n];
	}
}

如果题目要求内存依旧是像平时那样64MB的话,这个代码可以完美的通过,然而,这道题的内存限制是1MB,下面的代码会内存超限,所以,我列举出了很多第二个人赢得数据,如下:
2 4 6 15 17 19 30 32 34 36 45 47 49 51
终于,我神奇的发现一个规律,当n%15==0或2或4或6时都是第二个人赢,其余情况那自然就是第一个人赢了,所以,写出如下代码:

#include<iostream>
using namespace std;
int main(){
	int n;
	cin>>n;
	if(n%15==0)cout<<0;
	else if(n%15==2)cout<<0;
	else if(n%15==4)cout<<0;
	else if(n%15==6)cout<<0;
	else cout<<1;
}

然后,就在这严峻的内存限制下,做出了这道题.
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值