Poj 1061 青蛙的约会(扩展欧几里得解线性同余式)
一、Description
我们把这两只青蛙分别叫做青蛙A和青蛙B,并且规定纬度线上东经0度处为原点,由东往西为正方向,单位长度1米,这样我们就得到了一条首尾相接的数轴。设青蛙A的出发点坐标是x,青蛙B的出发点坐标是y。青蛙A一次能跳m米,青蛙B一次能跳n米,两只青蛙跳一次所花费的时间相同。纬度线总长L米。现在要你求出它们跳了几次以后才会碰面。
Input
Output
二、题目分析
这道题用到了扩展欧几里得算法解线性同余问题,小弟数论没怎么学。今天看到一篇精辟的题解,于是略作修改,引用之。原文请看http://blog.csdn.net/swordholy/article/details/4423543
根据题意可知,题目要求的是求(X + K * M)mod L=(Y + K * N)mod L这个模方程的k的最小整数解;跟据模的性质对这个方程变形得:K * ( M - N ) + T * L=Y--X( T为引进的一整数);
令A= (M - N) ; B = Y - X; 得:K * A + T * L =B ( 0)
看到这个式子是不是感觉很眼熟,对,它就是扩展欧几里得法能解的标准方程A * X + B * Y= D 的标准形;唯一的不同是扩展欧几里得D 是前面两系数A,B的最大公约数;而(0)式中的B就不能保证了。
1、不过没关系,先用扩展欧几里得得出K * A + T *L=gac(A,L) 的一个解k0,t0;再观察两个式子:
K * A + T * L =B ( 0)
K0 * A + T0 * L=D (1) (令D = gcd(A,L))
将(0)式两边都除以D,得:
K * (A / D)+ T * (L /D)=B/D
因为D为A,B的最大公约数,所以A / D,L / D为整数,所以B / D必定为整数,否则方程无解;
将(1)式两边都乘以B / D 与( 0 )式比较:
K * A + T * L =B ( 0)
K0 *( B / D) * A + T0 *( B / D)* L=B (1)
得K = K0 * B / D; T = T0 * B / D;
2、接下来就是由一个解扩展成一个解系:
( 1)除以D得: K0 * (A / D ) + T0 * ( L / D)=1
因为(A / D )和( L / D)互质,将方程写成:
(K0 + U * ( L / D)) * (A / D ) + ( T0 + V * (A / D ) ) * ( L / D)=1;
只要U * ( L / D) * (A / D ) + V * (A / D ) ) * ( L / D)=0成立就行;
所以K ,T 的解系可以写成 k = (K0 + U * ( L / D)) * (B / D ) ,T=( T0 + V * (A / D ) ) * ( B / D)
接下来就是求k的最小整数解了;
因为K = (K0 mod (L / D) + (U + K0 / ( L / D) ) * ( L / D)) * (B / D);
所以Kmin=(K0 * (B / D)) mod (L / D);
3、 大功基本高成了,还差最后一步,那就是如何用扩展欧几里得解K * A + T * L=gac(A,L)
对A * X + T * L = D;
递归调用时令A = B ; B = A % B;(辗转相除法,求最大公约数)
将其变为形式(2) B * X + A % B * Y = D;
变形:B * X + A * Y - (A / B) * B * Y = D;
再变:A * Y+ B ( X - A / B * Y)=D; (3)
与(2)式B * X + A % B * Y = D;比较:
得:
当A = B ; B = A % B时:X = Y ; Y = X - A / B * Y;调用过程中的X , Y 就是对应的A , B 的解;当回到顶层时,A , B 就 是最初的A ,B,所以此时的X,Y就是所求解。
三、Java代码
import java.util.Scanner;
public class Main {
static long x0, y0;
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
long x = scan.nextInt();
long y = scan.nextInt();
long m = scan.nextInt();
long n = scan.nextInt();
long L = scan.nextInt();
if (x > y) {
long t = y;
y = x;
x = t;
t = n;
n = m;
m = t;
}
long a = Math.abs(m - n);
long b = L;
long c;
if (m > n) {
c = y - x;
} else {
c = x - y + L;
}
long d = gcd(a , b);
if(c%d!=0){
System.out.println("Impossible");
}else{
long add1 = x0*c/d ;
long add2 = Math.abs(b/d);
while( add1 <0 ){
add1 += add2;
}
while(add1 - add2 >= 0){
add1 -= add2;
}
System.out.println(add1);
}
}
public static long gcd(long a, long b) {
long t, d;
if (b == 0) {
x0 = 1;
y0 = 0;
return a;
}
d = gcd(b, a % b);
t = x0;
x0 = y0;
y0 = t - a / b * y0;
return d;
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
Poj 1061 青蛙的约会(扩展欧几里得解线性同余式)的更多相关文章
- poj 1061 青蛙的约会 (扩展欧几里得模板)
青蛙的约会 Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Submit Status ...
- POJ - 1061 青蛙的约会 扩展欧几里得 + (贝祖公式)最小正整数解
题意: 青蛙 A 和 青蛙 B ,在同一纬度按照相同方向跳跃相同步数,A的起点为X ,每一步距离为m,B的起点为Y,每一步距离为 n,一圈的长度为L,求最小跳跃步数. 思路: 一开始按照追击问题来写, ...
- POJ 1061 青蛙的约会 扩展欧几里得
扩展欧几里得模板套一下就A了,不过要注意刚好整除的时候,代码中有注释 #include <iostream> #include <cstdio> #include <cs ...
- poj 1061 青蛙的约会 拓展欧几里得模板
// poj 1061 青蛙的约会 拓展欧几里得模板 // 注意进行exgcd时,保证a,b是正数,最后的答案如果是负数,要加上一个膜 #include <cstdio> #include ...
- POJ.1061 青蛙的约会 (拓展欧几里得)
POJ.1061 青蛙的约会 (拓展欧几里得) 题意分析 我们设两只小青蛙每只都跳了X次,由于他们相遇,可以得出他们同余,则有: 代码总览 #include <iostream> #inc ...
- poj 1061 青蛙的约会+拓展欧几里得+题解
青蛙的约会+拓展欧几里得+题解 纵有疾风起 题意 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出 ...
- pku 1061 青蛙的约会 扩展欧几里得
青蛙的约会Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 120482 Accepted: 25449Description 两只青 ...
- POJ 1061 青蛙的约会(欧几里得扩展)
题意:已知青蛙1位置x,速度m,青蛙2位置y,速度n,纬线长度为l,求他们相遇时最少跳跃次数. 思路:设最小跳跃次数为k,则(x + k*m) - (y + k*n) = q*l:经过整理得到k*(n ...
- [poj1061]青蛙的约会<扩展欧几里得>
题目链接:http://poj.org/problem?id=1061 其实欧几里得我一直都知道,只是扩展欧几里得有点蒙,所以写了一道扩展欧几里得裸题. 欧几里得算法就是辗转相除法,求两个数的最大公约 ...
随机推荐
- 九度OJ 1354:和为S的连续正数序列 (整除)
时间限制:2 秒 内存限制:32 兆 特殊判题:否 提交:2028 解决:630 题目描述: 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100.但是他并不 ...
- 我的Android进阶之旅------>Android疯狂连连看游戏的实现之加载界面图片和实现游戏Activity(四)
正如在<我的Android进阶之旅------>Android疯狂连连看游戏的实现之状态数据模型(三)>一文中看到的,在AbstractBoard的代码中,当程序需要创建N个Piec ...
- PAT 1054. 求平均值 (20)
本题的基本要求非常简单:给定N个实数,计算它们的平均值.但复杂的是有些输入数据可能是非法的.一个“合法”的输入是[-1000,1000]区间内的实数,并且最多精确到小数点后2位.当你计算平均值的时候, ...
- 机器学习Coursera学习总结
Coursera上Andrew NG的机器学习实在是太火了,最近有时间花费了20来天的时间(每天3小时左右)终于学习完了全部的课程,总结如下: (1)适合入门,讲的比较基础,Andrew讲的很棒: ( ...
- eclipse 修改 JDK中的src.zip的路径
http://blog.sina.com.cn/s/blog_54a1bca7010112fb.html http://www.douban.com/note/211369821/ 1.点 “wind ...
- Kattis - names Palindrome Names 【字符串】
题目链接 https://open.kattis.com/problems/names 题意 给出一个字符串 有两种操作 0.在字符串的最末尾加一个字符 1.更改字符串中的一个字符 求最少的操作步数使 ...
- HackerRank - flipping-the-matrix 【数学】
题意 一个矩阵中 每一行 每一列 都可以倒置 在不断进行倒置后 求 左上的那个 N * N 矩阵 的和 最大为多少 思路 M = 2 * N 通过 倒置特性 我们可以发现,最左上的那个矩阵 第 [I] ...
- curl简单封装 get post
Curl.php <?php /** * Class Curl curl简单封装 get post */ class Curl { /** * @brief get请求 * @param $ur ...
- day6 装饰器总结
装饰器:开放封闭原则,为一个函数加上新的功能,不改变原函数,不改变调用方式 def fun2(wtf): def fun3(): print('i am pythoner!!! ') wtf() re ...
- 同一台电脑关于多个SSH KEY管理
运用shh -T -v git@github.com查看具体出错信息,再根据信息来调试 原文链接: http://yijiebuyi.com/blog/f18d38eb7cfee860c117d ...