hdu6869 Slime and Stones // 威佐夫博弈·改

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

威佐夫博弈原本是每次操作任取某堆的任意个石头1,或是从两堆中分别取出相同数量的石头2

方程为:

      1 / t + 1 / t + 1 = 1;

操作2修改为取出石头数量之差不超过k,即本题含义时,方程可为:

      1 / t + 1 / 1 + k + t = 1;

 判定条件为: an = n * t;

           bn = an + (k + 1) * n;

 若属于数列元素——lose  其余点——win  [本题中讨论先手情况]

本文借鉴CSDN某萌萌哒大佬:https://blog.csdn.net/qq_43814654/article/details/108086427

*转载请附链接 谢谢

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<string>
 5 #include<cstdio>
 6 #include<cmath>
 7 
 8 #define ll long long
 9 
10 using namespace std;
11 
12 bool check(ll a, ll b, ll k)// 1/x + 1/1+k+x = 1 | x = ? 
13 {
14     long double K = k; 
15     long double t = (1.0 - K + sqrt(K * K + 2 * K + 5.0)) / 2.0;
16     //直接用long double 代入运算 方程解的精度很致命 
17         
18     ll l = 0, r = 1e9, mid;
19     while(l <= r){
20         mid = (l + r) >> 1;
21         ll tmp = (k + 1 + t) * mid;
22         if(b > tmp){
23             l = mid + 1;
24         }else if(b < tmp){
25             r = mid - 1;
26         }else{
27             if(a + (k + 1) * mid == b){
28                 return true;
29             }
30             break;
31         }
32     }    
33     return false;
34 }
35 
36 int main(){
37     int T;scanf("%d",&T);
38     while(T--){
39         ll a, b, k;
40         scanf("%lld%lld%lld",&a,&b,&k);
41         if(a > b)    swap(a, b);
42         if(check(a, b, k)){//true-lose false-win
43             printf("0
");
44         }else{
45             printf("1
");
46         }                
47     }
48         
49     return 0;
50 }
原文地址:https://www.cnblogs.com/ecustlegendn324/p/13530126.html