poj 2142 (解不定方程)

The Balance

  POJ - 2142 
考虑到 ax+by=d

假设解为正时代表在天平左边,解为负时代表在天平右边

通过拓展欧几里得解出一组解

然后通过不断枚举找出最优解

我直接-50000 到50000 枚举了....

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
#define LL long long

LL myabs(LL x)
{
    if(x<0)return -x;
    else return x;
}

LL exgcd(LL a,LL b,LL &x,LL &y)
{
    if(!b)
    {
        x=1,y=0;
        return a;
    }
    LL d=exgcd(b,a%b,x,y);
    LL t=x;
    x=y;
    y=t-a/b*y;
    return d;
}

int  main()
{
    LL a,b,d;
    LL x,y;
    while(cin>>a>>b>>d&& a&&b&&d)
    {
        LL c=exgcd(a,b,x,y);
        LL t=d/c;
        x*=t;
        y*=t;
        LL minl=99999999;
        LL sum=99999999;
        LL dx=b/c;
        LL dy=a/c;
        LL ax;
        LL ay;
        for(LL i=-50000;i<=50000;i++)
        {
            LL dx=x+i*(b/c);
            LL dy=y-i*(a/c);
            if(myabs(dx)+myabs(dy)<=minl&&myabs(dx)*a+myabs(dy)*b<=sum)
            {
                minl=myabs(dx)+myabs(dy);
                sum=myabs(dx)*a+myabs(dy)*b;
                ax=myabs(dx);
                ay=myabs(dy);
            }
        }
        cout<<ax<<" "<<ay<<endl;
    }
}

补充:

x+y 最小说明解一定在 x=x0+t*(b/c)  y=y0-t*(b/c);x=0,y=0,附近

所以令x=0 ,y=0 解得t1=-x0/(b/c)  t2=y0/(a/c);

直接在t1,t2范围内枚举就好了.

猜你喜欢

转载自blog.csdn.net/weixin_40894017/article/details/80436317