zoukankan      html  css  js  c++  java
  • 扩展欧几里求最优解

    https://zoj.pintia.cn/problem-sets/91827364500/problems/91827369176

    题意:有一数轴 , 问从A点到B点最少需要几步。可以有6中方式行走,左右a , b a+b.

    解法:设走了x步a , y步b。有方程 ax + by = B-A ,转化为求|x| + |y|的最小值,x , y 分别是两条直线。

    |x|+|y|最小值在x=x+bt与y=y-at两条直线交点附近。

    #include <bits/stdc++.h>
    using namespace std;
    #define mem(a,b) memset(a,b,sizeof(a))
    #define cin(a) scanf("%d",&a)
    #define pii pair<int,int>
    #define ll long long
    #define gcd __gcd
    #define mod 1000000007
    #define INF  0x3f3f3f3f
    const ll inf = 0x3f3f3f3f;
    const int M = 1e9+7;
    const int N = 100009 ;
    ll x , y , d ;
    
    void gcd(ll a , ll b , ll &d , ll &x , ll &y)
    {
        if(b == 0)
        {
            x = 1 ;
            y = 0 ;
            d = a ;
        }
        else{
            gcd(b , a%b , d , x , y);
            ll t = x ;
            x = y ;
            y = t - (a/b) * y ;
        }
    }
    
    ll cal(ll a , ll b , ll c)
    {
        gcd(a , b , d , x , y);
        if(c % d) return -1 ;
        else{
            return 1;
        }
    }
    
    int main()
    {
        int t ;
        scanf("%d" , &t);
        while(t--)
        {
            ll A , B , a , b ;
            scanf("%lld%lld%lld%lld" , &A,&B , &a, &b);
            ll c = B - A ;
            ll t = cal(a , b , c);
            if(t == -1){
                cout << -1 << endl ;
                continue ;
            }
            else
            {
                x *= c / d ;
                y *= c / d ;
                a /= d ;
                b /= d ;
                ll ans = inf * inf , tmp ;//inf要用ll,在这wa了几发
                ll mid = (y - x) / (a + b);//mid为两直线交点
                for(ll T = mid - 1 ; T <= mid + 1 ; T++)
                {
                    if((x + b*T)*(y - a*T) >= 0)//x ,y 同号
                    {
                        tmp = max(abs(x+b*T) , abs(y-a*T));//取最大那个就可以,相同部分取x+y每步
                    }
                    else{
                        tmp = abs(x - y + (a + b) * T);//都取
                    }
                    ans = min(tmp , ans);
                }
                cout << ans << endl ;
            }
    
        }
    
        return 0;
    }
    
  • 相关阅读:
    2014 中华架构师大会 回想
    mybatis重拾---部署官方demo
    D 语言学习感受
    D语言学习
    D语言简介
    C++输入cin详解
    C++源文件的后缀名问题
    C 函数指针详解
    Linux下的五个查找命令:grep、find、locate、whereis、which
    Qt---QFtp上传、下载二进制文件
  • 原文地址:https://www.cnblogs.com/nonames/p/12171637.html
Copyright © 2011-2022 走看看