The Balance(扩展欧几里得模板题)

来源:互联网 发布:淘宝c店开店流程 编辑:程序博客网 时间:2024/06/07 06:48

【题目来源】:https://vjudge.net/problem/POJ-2142
【题意】
求解ax+by=c的关于x,y的和最小的一组解。
【思路】
解决二元一次方程组,不多说,直接扩展欧几里得模板套上。
然后,题目要求求出的x+y的值(绝对值)最小,所以先求出x0,y0,
推出第一个x1(最小非负数),通过关系式来求解相应的y1。
推出第一个y2(最小非负数),通过关系式来求解相应的x2。
比较这两组最优解,得出一个最最优解。
【代码】

#include<set>#include<map>#include<stack>#include<cmath>#include<queue>#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<limits.h>#include<algorithm>#define mem(a,b) memset(a,b,sizeof(a))using namespace std;const int mod=1e9+7;typedef unsigned long long ll;typedef long long LL;LL ab(LL a){    return a<0?-a:a;}LL exgcd(LL a,LL b,LL &x,LL &y){    if(b==0)    {        x=1;        y=0;        return a;    }    LL d=exgcd(b,a%b,y,x);    y-=a/b*x;    return d;}int main(){    LL a,b,c,x,y;    while(~scanf("%lld%lld%lld",&a,&b,&c))    {        if(!a&&!b&&!c)        {            break;        }        LL d=exgcd(a,b,x,y);        if(c%d)            printf("no solution\n");        else        {            LL x1=(c/d*x%(b/d)+(b/d))%(b/d);            LL y1=(c-a*x1)/b;            LL y2=(c/d*y%(a/d)+(a/d))%(a/d);            LL x2=(c-b*y2)/a;            if(ab(x1)+ab(y1)>=ab(y2)+ab(x2))            {                printf("%lld %lld\n",ab(x2),ab(y2));            }            else            {                printf("%lld %lld\n",ab(x1),ab(y1));            }        }    }}
阅读全文
0 0
原创粉丝点击