威佐夫博奕 || HDU 1257 || POJ 1067

两个人如果都采用正确操作,那么面对非奇异局势,先拿者必胜;反之,则后拿者取胜。

那么任给一个局势(a,b),怎样判断它是不是奇异局势呢?我们有如下公式:

ak =[k(1+√5)/2],bk= ak + k (k=0,1,2,...n 方括号表示取整函数)

奇妙的是其中出现了黄金分割数(1+√5)/2 = 1.618...因此,由ak,bk组成的矩形近似为黄金矩形,由于2/(1+√5)=(√5-1)/2,可以先求出j=[a(√5-1)/2],若a=[j(1+√5)/2],那么a = aj,bj = aj + j,若不等于,那么a = aj+1,bj+1 = aj+1 + j + 1,若都不是,那么就不是奇异局势。然后再按照上述法则进行,一定会遇到奇异局势。



m(k)= k * (1 + sqrt(5))/2
n(k)= m(k) + k

对于问题分析:

对于两队石子,形成局面(a,b);a小于b,如果不是,交换a,b;

判断它是否是奇异局势,我们得找到k值;

(0,0),(1,2),(3,5),(4,7),(6,10),(8,13)

我们发现,每组数据的间隔 b-a  就是第(b-a)组数据;

所以,k = b-a;


判断   floor(k*(1.0+sqrt(5.0))/2.0) 是否等于b;  double floor(double x)  为向下取整函数,头文件math.h

如果等于,则是奇异局势,反之则是非奇异局势;


代码如下

#include <iostream>
#include <cmath>
using namespace std; 
int main() 
{ 
    int m,n; 
    while(cin>>m>>n) 
    {
		if (m > n) { int temp; temp = m; m = n; n =temp; }
		int k = n - m;
		int data = floor(k*(1.0+sqrt(5.0))/2.0); 
		if (data == m) cout<<0<<endl; 
		else cout<<1<<endl;
    } 
}



你可能感兴趣的:(威佐夫博奕 || HDU 1257 || POJ 1067)