威佐夫博弈

威佐夫博弈(Wythoff’s game):

题目链接

有两堆各若干个物品,两个人轮流从任一堆取至少一个或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜。

分析
这种情况下是颇为复杂的。
我们用(a[k],b[k])(a[k] ≤ b[k] ,k=0,1,2,…,n)表示两堆物品的数量并称其为局势,如果甲面对(0,0),那么甲已经输了,这种局势我们称为必败点。
前几个必败点是:(0,0)、(1,2)、(3,5)、(4,7)、(6,10)、(8,13)、(9,15)、(11,18)、(12,20)。(注:k表示奇异局势的序号, 第一个奇异局势k=0)
可以看出,a[0]=b[0]=0,a[k]是未在前面出现过的最小自然数,而 b[k]= a[k] + k。

结论
a[k]=(b[k]-a[k])*k;
k=0.618 (黄金分割率)
常用 double k=(sqrt(5.0)+1)/2来做精确值。

题解
所以只需判断k*(b[k]-a[k])是否等于a[k]即可

Code

#include<bits/stdc++.h>
#define IO  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std; 
 
const int inf=0x3f3f3f3f;
typedef long long ll; 
const int N=100007;
const ll mod=998244353;     

int main(){ 
    IO;
    int t=1;
    cin>>t;
    while(t--){ 
        ll n,x;
        cin>>n>>x;
        ll a=n-x,b=x-1;
        if(a>b)swap(a,b);
        double m=(sqrt(5.0)+1.0)/2.0;
        ll y=(b-a)*m;
        if(y!=a)cout<<"yo xi no forever!"<<endl;
        else cout<<"ma la se mi no.1!"<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值