扩展欧几里德算法。模板题。
根据题目的意思。
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; }