【bzoj4147】 [AMPPZ2014]Euclidean Nim

本文详细解析了一种名为Euclidean Nim的数学博弈问题,通过分析不同状态下博弈双方的策略选择,得出了解决该问题的具体算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这题不错啊。。。
E操作时,若n>p则任意取p的倍数,否则+p
P操作时同理。
问最终谁会取完。

exciting!推了三节数学课(雾)!

首先可以打表看看规律……然而并没有什么卵用
注意到标题是Euclidean Nim,猜测这题和Euclid肯定有关系(斜眼),然后可以尝试用扩欧手动模拟一下,胡乱搞搞。

画出几十棵博弈树后就可以大概猜出结果肯定和n,p,q的大小关系有关

以下来推结论。

首先无解的情况只有一种,就是gcd(p,q)n,这个可以通过扩欧ax+by=d来理解,这个方程无解当且仅当gcd(x,y)d

那么对于别的情况一定有gcd(p,q)n,在一开始把p,q,n都除掉gcd(p,q)也不会影响结果。


Statu  0
显然当p==q时必有p==1
故此时(p,q,n)为必胜态


Status  1
p>n,p>q
此时状态(p,q,n)只能转移到(q,p,n+p),因为p只能往上加
接着只需要转移成(p,q,(n+p) mod q),此时(n+p) mod q<p,q<p,故p仍然只能往上加
如此反复p永远没有取走石子的机会,则q必定会取完所有石子。


Status  2
np>q
此时(p,q,n)比较复杂
首先如果转移到了某个状态(q,p,x),其中xq,那么q可以将其转移成(p,q,x mod q),变成了Status 1,p必败。
因此十分机智的p是肯定不会将现在状态变成那样的。
为了方便讨论,p取到了n mod p,当然必须要有n mod p<q否则还是得挂。这个时候变成了(q,p,x),其中x=n mod p,x<q,傲娇的p和q开始了这样(p,q,x+q)>(q,p,x+qp)>(p,q,x+qp+q)>(q,p,x+qp+qp)……若p要胜,则需要有(nq)(n mod p)
故此时(p,q,n)为必胜态当且仅当(nq)(n mod p) && n mod p<q


Status 3
p<n,p<q
(p,q,n)(q,p,n mod p),此时q>p,q>n mod p,q必败,则原状态必胜。


Status 4
q>p>n
(p,q,n)(q,p,n+p)
n+pq,则转到Status 2
否则即为Status 1,必败,原状态必胜。


#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define stop(x) return puts(x) , 0

inline int rd() {
    char c = getchar();
    while (!isdigit(c)) c = getchar() ; int x = c - '0';
    while (isdigit(c = getchar())) x = x * 10 + c - '0';
    return x;
}

int gcd(int a , int b) { return b ? gcd(b , a % b) : a ; }

bool check(int p , int q , int n) {
    n %= p;
    return n < q && n % (p - q) == 0;
}

int p , q , n;

int solve() {
    p = rd() , q = rd() , n = rd();
    int g = gcd(p , q);
    if (n % g)
        stop("R");
    p /= g , q /= g , n /= g;
    if (p == q)
        stop("E"); // status 0
    if (p > n) {
        if (p > q)
            stop("P"); // status 1
        else if (q > p) { // status 4
            if (n + p < q)
                stop("E"); //4 - section 2
            else
                stop(check(q , p , n + p) ? "P" : "E"); //4 - section 1
        }
    } else {
        if (p > q)
            stop(check(p , q , n) ? "E" : "P"); // status 2
        else
            stop("E"); // status 3
    }
}

int main() {
    #ifndef ONLINE_JUDGE
    //  freopen("data.txt" , "r" , stdin);
    #endif
    int T = rd();
    while (T --)
        solve();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值