zsyzlzy

导航

 

NIM博弈

裸题题意:
有n堆石子,两个绝顶聪明的人轮流操作,每次操作为取走一堆中的若干个石子,取走最后一个石子的人获胜,问先手是否能赢。

这显然是一个公平组合问题——不能行动者败。
显然,当所有堆的石子数为0,必败,此时
a[1]xor⁡a[2]xor⁡……a[n]=0a[1] \operatorname{xor} a[2] \operatorname{xor}……a[n]=0.
不管一个人进行什么样的操作,另一个人总能把异或值调整回来。

所以如果a[1]xor⁡a[2]xor⁡……a[n]≠0a[1] \operatorname{xor} a[2] \operatorname{xor}……a[n]\ne 0,
先手给后手一个a[1]xor⁡a[2]xor⁡……a[n]=0a[1] \operatorname{xor} a[2] \operatorname{xor}……a[n]= 0的状态,
那么以后每次先手也总能给后手一个a[1]xor⁡a[2]xor⁡……a[n]=0a[1] \operatorname{xor} a[2] \operatorname{xor}……a[n]= 0的状态(直到石子数为零)

综上:若a[1]xor⁡a[2]xor⁡……a[n]≠0a[1] \operatorname{xor} a[2] \operatorname{xor}……a[n]\ne 0,先手必胜。反之,先手必败。

传送门

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define g getchar()
using namespace std;
int t,n,a,b;
void qr(int &x)
{
	char c=g;x=0;
	while(!('0'<=c&&c<='9'))c=g;
	while('0'<=c&&c<='9')x=x*10+c-'0',c=g;
}
int main()
{
	qr(t);
	while(t-->0)
	{
		qr(n);qr(a);
		while(--n>0)qr(b),a^=b;
		if(a)puts("Yes");
		else puts("No");
	}
	return 0;
}

威佐夫博弈

题意:
有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取完者为胜者。现在给出初始的两堆石子的数目,如果轮到你先取,假设双方都采取最好的策略,问最后你是胜者还是败者。

前置知识:Beatty 定理

内容:
设a、ba、b是正无理数且 1a+1b=1。\dfrac{1}{a} +\dfrac{1}{b} =1。记P={⌊at⌋∣t∈N+},Q={⌊bt⌋∣t∈N+}P=\{ \lfloor{at}\rfloor | t\in N+\},Q=\{ \lfloor{bt}\rfloor | t\in N+\},则P与QP与Q是N+N+的一个划分,即P∩QP∩Q为空集且P∪Q为正整数集合N+P∪Q为正整数集合N+。

证明

  1. 任一个正整数至多在集合P或Q中出现一次因为a、b为正且1a+1b=1,任一个正整数至多在集合P或Q中出现一次 因为a、b为正且 \dfrac{1}{a} +\dfrac{1}{b} =1,则a、b>1a、b>1,所以对于不同的正整数t,⌊at⌋各不相同,类似对b有相同的结果。所以对于不同的正整数t,\lfloor{at}\rfloor各不相同,类似对b有相同的结果。因此任一个整数至多在集合P或Q中出现一次。因此任一个整数至多在集合P或Q中出现一次。
  2. 现证明P∩Q为空集:(反证法)假设k为P∩Q的一个正整数,则存在正整数m、n使得⌊ma⌋=⌊nb⌋=k。即k<ma、nb<k+1,现证明P∩Q为空集:(反证法)假设k为P∩Q的一个正整数,则存在正整数m、n 使得\lfloor{ma}\rfloor=\lfloor{nb}\rfloor=k。即k < ma、nb<k+1,等价地改写不等式为 mk+1<1a<mk及nk+1<1b<nk\dfrac{m}{k+1}< \dfrac{1}{a} < \dfrac{m}{k}及\dfrac{n}{k+1}< \dfrac{1}{b} < \dfrac{n}{k}。相加起来得
    m+nk+1<1<m+nk,即k<m+n<k+1。这与m、n为整数有矛盾,所以P∩Q为空集.\dfrac{m+n}{k+1} < 1 <\dfrac{m+n}{k} ,即 k < m+n < k+1。这与m、n为整数有矛盾,所以P∩Q为空集.
  3. 现证明N+=P∪Q:现证明N+=P∪Q:
    已知P∪Q是N+的子集,剩下来只要证明N+是P∪Q的子集。已知P∪Q是N+的子集,剩下来只要证明N+是P∪Q的子集。
    (反证法)假设存在k∈N+且k∉P∪Q,(反证法)假设存在k\in N+且k\notin P∪Q ,
    则存在正整数m、n使得⌊ma⌋<k<⌊(m+1)a⌋、⌊nb⌋<k<⌊(n+1)b⌋则存在正整数m、n使得\lfloor{ma}\rfloor<k <\lfloor{(m+1)a}\rfloor、\lfloor{nb}\rfloor< k <\lfloor{(n+1)b}\rfloor
    由此得ma<k≤⌊(m+1)a⌋−1<(m+1)a−1(因为a是无理数),类似地有nb<k≤⌊(n+1)b⌋−1<(n+1)b−1。由此得ma < k \le\lfloor{ (m+1)a}\rfloor-1<(m+1)a -1(因为a是无理数),类似地有nb < k \le \lfloor{ (n+1)b}\rfloor-1<(n+1)b -1。
    等价地改写为mk<1a<m+1k+1及nk<1b<n+1k+1。两式加起来,得m+nk<1<m+n+2k+1,即m+n<k<k+1<m+n+2。这与m,n,k皆为正整数矛盾。等价地改写为 \dfrac{m}{k} < \dfrac{1}{a}< \dfrac{m+1}{k+1}及 \dfrac{n}{k} < \dfrac{1}{b}< \dfrac{n+1}{k+1}。两式加起来,得 \dfrac{m+n}{k} < 1 < \dfrac{m+n+2}{k+1} ,即m+n < k < k+1 < m+n+2。这与m, n, k皆为正整数矛盾。

设两堆石头个数为x,y(x≤y)x,y(x\le y).
则必败态如下:

xx yy
0 0
1 2
3 5
4 7
6 10
8 13
…… ……

可以发现xi+i=yix_i+i=y_i,X,Y为Beatty序列X,Y为Beatty序列.
首先,简单证明一下必败的充分性:
对于xi,yi,令xi减小或yi减小或xi同时减小相同的值都不能到达其他必败态。对于x_i,y_i,令x_i减小或y_i减小或x_i同时减小相同的值都不能到达其他必败态。

设xi=⌊a∗i⌋,yi=⌊b∗i⌋(1a+1b=1)x_i=\lfloor{a*i}\rfloor,y_i=\lfloor{b*i}\rfloor(\dfrac{1}{a} +\dfrac{1}{b} =1)(满足Beatty定理)
因为xi+i=yix_i+i=y_i
即⌊ai+i⌋=⌊b∗i⌋\lfloor{ai+i}\rfloor=\lfloor{b*i}\rfloor
⌊(a+1)∗i⌋=⌊b∗i⌋\lfloor{(a+1)*i}\rfloor=\lfloor{b*i}\rfloor
所以a+1=ba+1=b.
代入1a+1b=1\dfrac{1}{a} +\dfrac{1}{b} =1,可得a=5+12a=\dfrac{\sqrt5+1}{2}
所以我们就可以得到通项公式了。

传送门
代码:

#include<cstdio>
#include<algorithm>
using namespace std;
int main() {
	int x,y,a;
	while(~scanf("%d%d",&x,&y)) {
		if(x>y)swap(x,y);
		a=(y-x)*1.6180339887498948482045868343656;
		putchar((x!=a)+'0');puts("");
	}
	return 0;
}

未完待续……

posted on 2019-10-14 14:59  zsyzlzy  阅读(243)  评论(0)    收藏  举报