扩展欧几里德算法。模板题。
根据题目的意思。
ax+by=c,已知a、b、c,求解使该等式成立的一组x,y。
a,b的最大公约数为gcd(a,b)。如果c不是gcd(a,b)的倍数,则该等式无解,因为等式左边除以gcd(a,b)是整数,而等式右边除以gcd(a,b)后为小数。
因此,只有当c是gcd(a,b)的倍数的时候,该等式有解。这样,可以通过计算使ax1+by1=gcd(a,b)成立的x1、y1,然后有x=(c/gcd(a,b))*x1,y=(c/gcd(a,b))*y1,得到x,y。
问题就被转换为求使ax+by=gcd(a,b)成立的一组x,y。这可以用扩展欧几里德算法求解。
#include <stdio.h>
#include <math.h>
void gcd(long long a,long long b,long long& d,long long& x,long long& y)
{
if(!b) { d=a; x=1; y=0; }
else { gcd(b, a%b, d, y, x); y-=x*(a/b); }
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
long long a,b,c,d,k,x,y;
scanf("%lld%lld",&c,&k);
a=floor(1.0*c/k);
b=ceil(1.0*c/k);
gcd(a,b,d,x,y);
x*=c/d;
y*=c/d;
printf("%lld %lld\n",x,y);
}
return 0;
}
做完题目发现网上有大牛给出了另一种解法,题目比较特殊,只要输出一组任意解即可。供参考。
#include <stdio.h>
int main()
{
int T, x, k;
scanf("%d", &T);
while (T--)
scanf("%d%d", &x, &k),printf("%d %d\n", k - x % k, x % k);
return 0;
}