1. 程式人生 > >NYOJ 837 Wythoff Game(威佐夫博奕公式利用)

NYOJ 837 Wythoff Game(威佐夫博奕公式利用)



Wythoff Game

時間限制:1000 ms  |  記憶體限制:65535 KB 難度:1
描述

最近ZKC同學在學博弈,學到了一個偉大的博弈問題--威佐夫博弈。
相信大家都學過了吧?沒學過?沒問題。我將要為你講述一下這個偉大的博弈問題。
有兩堆石子,數量任意,可以不同。遊戲開始由兩個人輪流取石子。
遊戲規定,每次有兩種不同的取法:
一是可以在任意的一堆中取走任意多的石子;
二是可以在兩堆中同時取走相同數量的石子。
最後把石子全部取完者為勝者。
我們今天要做的是求前n個必敗態。
什麼是必敗態?比如我們把(a,b)稱為一種狀態,a,b分別為兩堆石子中所剩的數目。如果a=0,b=0,我們說該種狀態為必敗態,因為我不能再進行遊戲,即使是可以進行,那也是必敗的,你知道,遊戲的我們都是非常聰明的。(0,0)(1,2)(3,5)...都是必敗態,我們今天要做的就是求前n個必敗態。不會?好吧!
我再告訴你:假設第n個必敗態為(a,b)a為前n-1個必敗態中沒有出現的最小自然數,b=a+n。這下大家應該明白了吧。好吧,我們的任務就的要前n個必敗態。規定第0個必敗態為(0,0)。

輸入
多組資料。
輸入為一個數n(0<=n<=100000)。
輸出
按照要求求出前n個必敗態。輸出格式看下面樣例。
樣例輸入
3
1
樣例輸出
(0,0)(1,2)(3,5)(4,7)
(0,0)(1,2)
提示
注意:每種情況中間沒有空格

水題啦,利用威佐夫博奕公式很快就AC了

程式碼如下:

#include<cstdio>
#include<cmath>
int a[100010],b[100010];

void dabiao()
{
	int i;
	for(i=0;i<=100000;++i)
	{
		a[i]=(int)(i*(1.0+sqrt(5.0))/2);
		b[i]=a[i]+i;
	}
}

int main()
{
	dabiao();
	int n,i;
	while(scanf("%d",&n)!=EOF)
	{
		for(i=0;i<=n;++i)
		   printf("(%d,%d)",a[i],b[i]);
		printf("\n");
	}
	return 0;
}