poj 1061 青蛙的约会(扩展gcd)
题意:两只青蛙从数轴正方向跑,给出各自所在位置, 和数轴长度,和各自一次跳跃的步数,问最少多少步能相遇。
分析:(x+m*t) - (y+n*t) = p * L;(t是跳的次数,L是a青蛙跳的圈数跟b青蛙的圈数之差。整个就是路程差等于纬度线周长的整数倍)。
(x+m*t)- (y+n*t) = p*L;
(n-m)*t + p*L = x - y;
令a = n-m; b = L; c = x-y; d = gcd(a, b);
a *t + b*p = c;
这道题的思路都是看的这个博客 , 这个博客里有这个题目的推导,还有扩展gcd的推导。
AC代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #define LL long long 6 using namespace std; 7 8 void exgcd(LL a, LL b, LL &d, LL &x, LL &y) 9 { 10 if(!b) {d = a; x = 1; y = 0;} 11 else{ exgcd(b, a%b, d, y, x); y -= x*(a/b); } 12 } 13 int main() 14 { 15 LL a, b, d, c; 16 LL x, y, m, n, l; 17 cin>>x>>y>>m>>n>>l; 18 a = n-m; 19 b = l; 20 c = x - y; 21 exgcd(a, b, d, x, y); 22 if(c%d!=0) 23 printf("Impossible\n"); 24 else 25 { 26 LL q; 27 q = b/d; 28 printf("%lld\n", (x*(c/d)%q+q)%q); 29 } 30 31 return 0; 32 }
扩展gcd模板:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #define LL long long 6 using namespace std; 7 8 void exgcd(LL a, LL b, LL &d, LL &x, LL &y) 9 { 10 if(!b) {d = a; x = 1; y = 0;} 11 else{ exgcd(b, a%b, d, y, x); y -= x*(a/b); } //一定注意括号(a/b); 12 } 13 int main() 14 { 15 LL a, b, d, x, y; 16 while(cin>>a>>b) 17 { 18 exgcd(a, b, d, x, y); 19 printf("%lld %lld %lld %lld %lld\n", a, x, b, y, d); 20 } 21 return 0; 22 }