HDU 6869-Slime and Stones【威佐夫博弈拓展】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6869

分析

显然,当 (k=1) 时,直接就是威佐夫博弈。

威佐夫博弈的必败态 ((a,b)) 的通项公式:

[a_i=[i·f],b_i=a_i+i (i=0,1,2,...) ,f=frac{sqrt{5}+1}{2},[x]表示取整 ]

考虑 (k=1) 的情况,推导前面几项 ((a,b),aleq b)

[(0,0),(1,3),(2,6),(4,10),(5,13),(7,17),(8,20)... ]

由此,可以发现:(b_i=a_i+2·i (i=0,1,2,3...))

采用和威佐夫博弈公式相同的推导方法,即 贝蒂定理(Betty Theorem):

介绍:https://zhuanlan.zhihu.com/p/149621032

威佐夫博弈的公式来自于:

[frac{1}{x}+frac{1}{x+1}=1 ]

解得:(x=frac{sqrt{5}+1}{2})

列出方程:

[frac{1}{x}+frac{1}{x+k+1}=1 ]

根据二元一次方程的通解:(x=frac{-bpm sqrt{b^2-4ac}}{2a}=frac{(1-k)pm sqrt{k^2+2k+5}}{2})

取正解:(x=frac{1-k+sqrt{k^2+2k+5}}{2})

所以,

[egin{cases} a_i &= [frac{1-k+sqrt{k^2+2k+5}}{2}·i]\ b_i &= a_i+(k+1)*i=[frac{3-k+sqrt{k^2+2k+5}}{2}·i] end{cases} ]

验证时,先求出 (i=lfloor (b-a)/(k+1) floor),然后代入 (i) 的值,验证以上的两个通项公式。

代码

#include<bits/stdc++.h>

using namespace std;

int main()
{
    int T,a,b,k;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&a,&b,&k);
        if(a>b) swap(a,b);
        double k1=(1-1.0*k+sqrt(1.0*k*k+2.0*k+5.0))/2.0;
        double k2=(3+1.0*k+sqrt(1.0*k*k+2.0*k+5.0))/2.0;
        int d=(b-a)/(k+1);
        if(floor(d*k1)==a&&floor(d*k2)==b) printf("0
");
        else printf("1
");
    }
    return 0;
}

参考博客:
https://blog.csdn.net/oampamp1/article/details/108083039
https://blog.csdn.net/qq_43814654/article/details/108086427

原文地址:https://www.cnblogs.com/1024-xzx/p/13527557.html