拓展欧几里得的通解的应用;
已知两个特解x0,y0,
通解 :x=x0+k*(b/gcd) y=y0-k*(a/gcd)
然后根据条件对一定范围内的解进行依次求解
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
ll a,b,d;
ll _abs(ll t)
{
if(t<0)
return -t;
return t;
}
ll _gcd(ll a,ll b,ll &x,ll &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
ll ans=_gcd(b,a%b,x,y);
ll tmp=x;
x=y;
y=tmp-(a/b)*y;
return ans;
}
void extend_gcd(ll a,ll b,ll c)
{
ll x,y;
ll gcd=_gcd(a,b,x,y);
x=x*c/gcd;//printf("x=%lld\n",x);转换为本方程的特解
y=y*c/gcd;//printf("y=%lld\n",y);
b/=gcd;
a/=gcd;
//printf("a=%lld b=%lld\n",a,b);
ll minn=inf,u,v;
ll p=_abs(x)/b;
ll q=_abs(y)/a;
for(ll i=-max(p,q)-1;i<=max(p,q)+1;i++)
{
ll j=i*b;
ll k=i*a;
if(_abs(x+j)+_abs(y-k)<minn)
{
u=_abs(x+j);
v=_abs(y-k);
minn=u+v;
}
if(_abs(x+j)+_abs(y-k)==minn)
{
if(_abs(x+j)*a+_abs(y-k)*b<a*u+b*v)
{
u=_abs(x+j);
v=_abs(y-k);
}
}
}
printf("%lld %lld\n",u,v);
}
int main()
{
while(scanf("%lld%lld%lld",&a,&b,&d),a||b||d)
{
extend_gcd(a,b,d);
}
return 0;
}