青蛙的約會-求解模線性同餘方程
1.問題描述:
兩隻青蛙在網上相識了,它們聊得很開心,於是覺得很有必要見一面。它們很高興地發現它們住在同一條緯度線上,於是它們約定各自朝西跳,直到碰面為止。可是它們出發之前忘記了一件很重要的事情,既沒有問清楚對方的特徵,也沒有約定見面的具體位置。不過青蛙們都是很樂觀的,它們覺得只要一直朝著某個方向跳下去,總能碰到對方的。但是除非這兩隻青蛙在同一時間跳到同一點上,不然是永遠都不可能碰面的。為了幫助這兩隻樂觀的青蛙,你被要求寫一個程式來判斷這兩隻青蛙是否能夠碰面,會在什麼時候碰面。 我們把這兩隻青蛙分別叫做青蛙A和青蛙B,並且規定緯度線上東經0度處為原點,由東往西為正方向,單位長度1米,這樣我們就得到了一條首尾相接的數軸。設青蛙A的出發點座標是x,青蛙B的出發點座標是y。青蛙A一次能跳m米,青蛙B一次能跳n米,兩隻青蛙跳一次所花費的時間相同。緯度線總長L米。現在要你求出它們跳了幾次以後才會碰面。
2.思路分析:因為兩隻青蛙有可能在繞彎大於一圈的維度才相遇到,這個問題實際上就是取餘的問題
x + k * m = L * t1+ 餘數
y + k * n = L * t2 + 餘數
方程兩邊相減:(m - n)*k + Lt = y - x;
本質其實就是解決線性方程:a x + b y = m的一個解的問題,因為其中涉及到求解的次數應該是大於零的,那麼求解的應該是第一個大於零的解
需要進行以下的處理:b /= d(d為a,b的最大公約數) x0 = (x%b + b)%b
程式碼如下:
import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner sc = new Scanner(System.in); int x = sc.nextInt();//座標 int y = sc.nextInt();//座標 int m = sc.nextInt();//A一次跳 int n = sc.nextInt();//B一次跳 int L = sc.nextInt();//緯度總長 int a = m - n; int b = L; m = y - x; long d; try { d = Ext_gcd.linearEquation(a, b, m); //System.out.println(d); long x0 = Ext_gcd.x; b /= d; b = Math.abs(b); x0 = (x0 % b + b) % b; System.out.println(x0); } catch (Exception e) { System.out.println("Impossible"); e.printStackTrace(); } } private static class Ext_gcd{ public static long x,y; public static long gcd(int a,int b){ if(b==0){ x = 1; y = 0; return a; } long res = gcd(b,a%b); long x1 = x; x = y; y = x1 - a / b * y; return res; } public static long linearEquation(int a,int b,int m) throws Exception{ long d = gcd(a,b); if(m%d!=0){ throw new Exception("無解"); }else{ long n = m / d; x *= n; y *= n; } return d; } } }