zoukankan      html  css  js  c++  java
  • ZOJ 3593 One Person Game(ExGcd + 最优解)题解

    思路:题意转化为求 (ax+by=dis) || (ax+cy=dis) || (bx+cy=dis) 三个式子有解时的最小|x| + |y|。显然求解特解x,y直接用扩展欧几里得,那么怎么求|x| + |y|?xy关系为一条直线,那么|x| + |y|应该是在x取0或者y取0的时候,但是要整数,所以只能在周围取几个点。我们知道x=x1+b/gcd*t,那么x1+b/gcd*t = 0可以解得 t  = -x1 * gcd / b。然后在附近取几个点。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define LS(n) node[(n)].ch[0]
    #define RS(n) node[(n)].ch[1]
    using namespace std;
    typedef long long ll;
    const int INF = 0x3f3f3f3f;
    const int maxn = 32767 + 10;
    
    ll ex_gcd(ll a, ll b, ll &x, ll &y){
        ll d, t;
        if(b == 0){
            x = 1;
            y = 0;
            return a;
        }
        d = ex_gcd(b, a%b, x, y);
        t = x-a/b*y;
        x = y;
        y = t;
        return d;
    }
    
    ll dis;
    //求|x|+|y|最小
    ll solve(ll a, ll b){
        ll x, y, d = ex_gcd(a, b, x, y);
        if(dis % d != 0) return INF;
        x = x * dis / d;
        y = y * dis / d;
        a /= d, b /= d;
        ll ans = abs(x) + abs(y);
    
        ll k;
        k = -x / b - 5;
        for(int i = 0; i <= 10; i++){
            ans = min(ans, abs(x + b * (k + i)) + abs(y - a * (k + i)));
        }
    
        k = y / a - 5;
        for(int i = 0; i <= 10; i++){
            ans = min(ans, abs(x + b * (k + i)) + abs(y - a * (k + i)));
        }
    
        return ans;
    }
    int main(){
        int T;
        scanf("%d", &T);
        while(T--){
            ll a, b, A, B;
            scanf("%lld%lld%lld%lld", &A, &B, &a, &b);
            dis = abs(A - B);
            ll ans;
            ans = min(solve(a, a + b), min(solve(a, b), solve(b, a + b)));
            printf("%lld
    ", ans == INF? -1 : ans);
        }
        return 0;
    }
  • 相关阅读:
    2019CSUST集训队选拔赛题解(二)
    2019CSUST集训队选拔赛题解(一)
    Dilworth定理
    直线石子合并(区间DP)
    后缀自动机 个人学习笔记
    HDU_6709 CCPC网络赛H 优先队列 贪心
    2019省赛翻车记
    【挖坑】某场组队训练找到的想要挖一挖的东西
    暑假补题需要点的技能点
    QAQorz的训练记录
  • 原文地址:https://www.cnblogs.com/KirinSB/p/9846574.html
Copyright © 2011-2022 走看看