世纪难题——取石子游戏——题解

wuzijie 2023-05-26 12:41:55 2023-05-26 13:03:40 4 返回题目

首先,这道题目描述非常不清晰

其实它的意思就是:

有一种有趣的游戏,玩法如下:

玩家:2 人;

道具:N 颗石子;

规则:

————游戏双方轮流取石子;

————每人每次取走若干颗石子(最少取 1 颗,最多取 K 颗);

————石子取光,则游戏结束;

————最后取石子的一方为胜。

假如参与游戏的玩家都非常聪明,问最后谁会获胜?

经过我细致地解释,你肯定已经理解了这一题

然后我们来分析

首先显然这题直接枚举每个人每一步的操作一定是行不通的

为了让我们的代码通过这题

我们可以使用 哈希 + 线段树

轻松过掉这道至少是黑题的题

AC代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
const int mod=1e9+7;
int n,k;
int a[N],tree[N<<2],tag[N<<2];
int h[N],pw[N];
vector<string>q[N];
int ls(int p) {
	return p<<1;
}
int rs(int p) {
	return p<<1|1;
}
void push_up(int p) {
	tree[p]=tree[ls(p)]+tree[rs(p)];
	return;
}
void build(int p,int pl,int pr) {
	tag[p]=0;
	if(pl==pr) {
		tree[p]=a[pl];
		return;
	}
	int mid=(pl+pr)>>1;
	build(ls(p),pl,mid);
	build(rs(p),mid+1,pr);
	push_up(p);
	return;
}
void addtag(int p,int pl,int pr,int d) {
	tag[p]+=d;
	tree[p]+=d*(pr-pl+1);
	return;
}
void push_down(int p,int pl,int pr) {
	if(tag[p]) {
		int mid=(pl+pr)>>1;
		addtag(ls(p),pl,mid,tag[p]);
		addtag(rs(p),mid+1,pr,tag[p]);
		tag[p]=0;
	}
	return;
}
void updata(int L,int R,int p,int pl,int pr,int d) {
	if(L<=pl&&pr<=R) {
		addtag(p,pl,pr,d);
		return;
	}
	push_down(p,pl,pr);
	int mid=(pl+pr)>>1;
	if(L<=mid)updata(L,R,ls(p),pl,mid,d);
	if(R>mid)updata(L,R,rs(p),mid+1,pr,d);
	push_up(p);
	return;
}
int query(int L,int R,int p,int pl,int pr) {
	if(L<=pl&&pr<=R)return tree[p];
	int mid=(pl+pr)>>1,res=0;
	push_down(p,pl,pr);
	if(L<=mid)res+=query(L,R,ls(p),pl,mid);
	if(R>mid)res+=query(L,R,rs(p),mid+1,pr);
	return res;
}
int gethash(int l,int r) {
	return((h[r]-h[l-1]*pw[r-l+1])%mod+mod)%mod;
}
int hassh(string book) {
	int res=0;
	for(int i=0; i<book.length(); i++)res=(book[i]+res*31%N);
	return res;
}
void insert(int key,string book) {
	int l=q[key].size();
	for(int i=0; i<l; i++)
		if(q[key][i]==book)
			return;
	q[key].push_back(book);
}
bool find(int key,string book) {
	int l=q[key].size();
	for(int i=0; i<l; i++)
		if(q[key][i]==book)
			return 1;
	return 0;
}
signed main() {
	scanf("%lld%lld",&n,&k);
	if(n%(k+1))cout<<1;
	else cout<<2;
	return 0;
}
{{ vote && vote.total.up }}