POJ 1067 取石子游戏

来源:互联网 发布:大数据时代 英文版 txt 编辑:程序博客网 时间:2024/05/17 23:43

这题我好不容易想到了必胜策略,但是不知道怎么算,悲剧。。。把我的思路整理如下

首先我发现了一些规律:

·规律1:形如(n,n+i)的石子,当i一定,至多只有一种(n,n+i)能是必败态。

这个比较好理解,假设(n,n+i)必败,那么(m,m+i),若m < n则一定都是必胜(要不然必败哪来的);若m > n则一定都是必胜(都可以转移到那个必败态去)

·规律2:如果(n,n+i)是必败态,形如(m,n+i)或(n,m)(其中前者m≠n,后者m≠n+i)都是必胜态

证明和上面也差不多。

接下来利用上面的规律
首先有一个很显然的i=1时 (1,2)为必败态
假设i=2时存在且仅存在一个必败态(n,n+i),则当n=3时可以符合定理2,则(3,5)为必败态
假设i=3时存在且仅存在一个必败态(n,n+i),则当n=4时可以符合定理2,则(4,7)为必败态

推的过程中会发现,每一次用到的n都是前面必败态的两堆石子数目中从来没有出现过的最小正整数。根据规律2可以证明他的正确性,根据规律1可以证明他的唯一性。

这一类数确定下来了,但是却不知道怎么算。。。
百度了一下,才知道这一类数的特点:
n=i*(1+sqrt(5))/2

#include<cstdio>#include<cmath>#include<algorithm>using namespace std;int main(){    int a, b;    while(scanf("%d%d",&a,&b)==2)    {        if(a>b)swap(a,b);        int k = b-a;        k = k*(1+sqrt(5))/2;        if(k==a)puts("0");        else puts("1");    }}
1 0
原创粉丝点击