威佐夫博弈
两堆石子,每次可以取一堆或两堆,从两堆中取得时候个数必须相同,先取完的获胜。
那么任给一个局势(a,b),怎样判断它是不是奇异局势呢?我们有如下公式:
ak =[k(1+√5)/2],bk= ak + k (k=0,1,2,…,n 方括号表示取整函数)
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> using namespace std; int n,m; int main() { double k=(1+sqrt(5.0))/2; while( cin>>n>>m ) { if( n>m ) swap(n,m); int t=m-n; if( n==(int) ( (double)t*k ) ) puts("0"); else printf("1\n"); } }
威佐夫博弈II
2020HDU暑假多校赛第九场 http://acm.hdu.edu.cn/showproblem.php?pid=6869
两堆石子,每次可以取一堆或两堆,从两堆中取得时候个数的差值小于等于k,先取完的获胜。
那么任给一个局势(a,b),怎样判断它是不是奇异局势呢?我们有如下公式:
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; ll readint(){ ll x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } ll a,b,k; int main(){ int T=readint(); while( T-- ) { a=readint(); b=readint(); k=readint(); if(a>b) swap(a,b); ll n=b-a; n/=(k+1); ld tmp=sqrt(k*k+2*k+5); ld x=(1-k+tmp)/2.0,y=(3+k+tmp)/2.0; if( (ll)(x*n)!=a || (ll)(y*n)!=b ) puts("1"); else puts("0"); } return 0; }