康熙环球/青蛙的约会
题目描述
话说西汉时期,汉武帝刘彻派遣张骞出使西域,欲同月氏国结交而共驱匈奴。
同时,月氏国也欲同大汉结交,也派出使者康破伦出使大汉,可是因为月氏国对于大汉的认知甚少,康破伦同样向西出使大汉。
一开始,张骞从大汉出发,康破伦从月氏国出发,两人都在同一纬度线上,张骞所处的经度为 xx,康破伦所处的经度为 yy
接下来,两人同时向西走,而且只能向西走,张骞每天走 mm 公里,康破伦每天走 nn 公里,且每天走路的速度不变,也不停下来休息
这样两人就在这一条长为 LL 的纬度线上一直向西走。
问:过了多少天之后张骞和康破伦会碰面,并磋商两国结交之事(所谓碰面,是指两人处在同一经度上)。
输入格式
输入只包括一行 55 个整数 x,y,m,n,Lx,y,m,n,L
输出格式
输出碰面所需要的天数
如果永远不可能碰面则输出一行 Impossible
样例
1 2 3 4 5
4
提示与说明
0 < x!=y≤2000000000
0 <m, n≤2000000000
0 <L≤2100000000
样例解释:
初始时二人位置: 1,21,2
走一步后: 4,14,1
两步: 2,52,5
三步: 5,45,4
四步: 3,33,3
此题可以列出方程x + km = y + kn(mod l),即k(m - n) – bl = y – x.
为了确定方程是否有整数解,方程两边同除gcd(m – n, l),再判断y – x是否能整除gcd(m – n, l),可以用exgcd求解。
1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 typedef long long ll; 5 ll x, y, m, n, l, s = 0, f, g, r; 6 ll exgcd(ll a, ll b, ll &u, ll &v) 7 { 8 if(!b) 9 { 10 u = 1; 11 v = 0; 12 return a; 13 } 14 r = exgcd(b, a % b, u, v); 15 ll t = u; 16 u = v; 17 v = t - a / b * v; 18 return r; 19 } 20 int main() 21 { 22 scanf("%lld %lld %lld %lld %lld", &x, &y, &m, &n, &l); 23 if(m == n) 24 { 25 printf("Impossible"); 26 return 0; 27 } 28 f = y - x; 29 g = m - n; 30 if(g < 0) 31 { 32 f = -f; 33 g = -g; 34 } 35 ll a, b; 36 exgcd(g, l, a, b); 37 if(f % r) 38 { 39 printf("Impossible"); 40 return 0; 41 } 42 a = (a * (f / r) % (l / r) + (l / r)) % (l / r); 43 printf("%lld", a); 44 return 0; 45 }