第六章 數學問題 -------- 6.9 天平稱重問題【線性同餘方程】青蛙的約會
模運算:
取模:計算除以m的餘數,叫做對m取模
同餘:將a,b對m取模的結果相同,記為 a ≡ b (mod m)(例如: x % 3 = 2 ===> x ≡ 2(%3),x餘3等於2,和2同餘),即 a mod m == b mod m 如果 a ≡ b (mod m),且c ≡ d (mod m),則有 a+b ≡ c+d (mod m) a*b ≡ c*d (mod m)
線性同餘方程:
a,b是整數,形如 ax ≡ b (mod n),且x是未知整數的同餘式稱為一元線性同餘方程。
定理:同餘方程 ax ≡ b (mod n) 對於未知數 x 有解,當且僅當 b 是 gcd(a,n)的倍數。否則方程無解。且方程有解時,方程有 gcd(a,n)個解。
這裡根據取餘的概念可以得出,假如 a%n = b 的話,可以寫出一個等式 a = n*t +b;
求解線性同餘方程的方法:這裡根據上面很容易得出下面兩個等式:
ax = n*y1 + 餘數
b = n*y2 + 餘數
上面兩式相減得 ax - b = n(y1-y2) ===> ax - b = ny ===> ax + ny = b; (這裡的未知數x y不用管正負號,因為最後求解出來的結果x y自帶正負號。)
那麼根據這個等式採用擴充套件歐幾里得演算法就能夠得出 x 的值。也就解出了線性同餘方程。
例題:青蛙的約會
思路:因為線總長L,青蛙需要迴圈跳才有可能碰面。而迴圈跳的話那麼它們的位置只能通過對L取餘得到(可以對比鐘錶轉圈理解)。根據題意,假設它們需要跳k次才能碰面,那麼很容易得出這個同餘組x+k*m ≡ y+k*n (mod L)。而根據上面的講解我們也可以得到下面兩個等式:
x + k*m = L*t1 + 餘數
y + k*n = L*t2 + 餘數
還是上面兩式相減得到 x - y + (m-n)*k = L * t ===> (m-n)*k + L * t = y - x 這裡已知的變數有 m n L y x,所以未知的變數為 k t
然後再對比擴充套件歐幾里得演算法求線性方程的等式 ax+by = m 所以可以得出 a = m - n,b = L,m = y - x。
然後根據上面寫程式碼即可:
import java.util.Scanner;
// 求解同餘方程的本質就是求線性方程
// 將求餘方程轉化為線性方程
public class 青蛙的約會 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
long x = scanner.nextInt(); // 座標
long y = scanner.nextInt(); // 座標
long m = scanner.nextInt(); // A第一次跳
long n = scanner.nextInt(); // B第一次跳
long l = scanner.nextInt(); // 維度總長
long a = m-n;
long b = l;
m = y-x;
long d = 0;
try {
d = ExtGcd.linearEquation(a, b, m);
} catch (Exception e) {
System.out.println("Impossible");
} // 求解線性方程
long x0 = ExtGcd.x;
b /= d; // 約一下
b = Math.abs(b); // 有可能小於0
/*=========這裡是AC的關鍵===========*/
x0 = (x0%b+b)%b; // 要求大於0的第一個解
System.out.println(x0);
}
// 私有的靜態的內部類
private static class ExtGcd{
static long x,y;
public static long ext_gcd(long a,long b){
if (b==0) {
x = 1;
y = 0;
return a;
}
long res = ext_gcd(b, a%b);
long x1 = x;
x = y;
y = x1-a/b*y;
return res;
}
public static long linearEquation(long a,long b,long m) throws Exception{
long d = ext_gcd(a, b);
if(m%d!=0) throw new Exception("無解");
long n = m / d;
x *= n;
y *= n;
return d;
}
}
}
結果:
相關文章
- 第六章 數學問題 -------- 6.1【巧用進位制】天平稱重問題
- 第六章 數學問題 -------- 6.10 特殊的同餘方程—逆元
- 第六章 數學問題 -------- 6.11【同餘方程組】POJ1006 生理週期
- 【組合數學】遞推方程 ( 有重根遞推方程求解問題 | 問題提出 )
- 洛谷 P1516 青蛙的約會 題解
- Hive SQL必刷練習題:同時線上人數問題(*****)HiveSQL
- [學習筆記] 丟番圖方程 & 同餘 & 逆元 - 數論筆記
- 第六章 數學問題 -------- 6.12 素數及質因數分解
- 第六章:線性方程與最大公因數(1)
- 第六章:線性方程與最大公因數(2)
- [每日一題] 第十七題:青蛙跳臺階問題每日一題
- 洛谷題單指南-線性表-P1996 約瑟夫問題996
- 【數學問題】最大公約數與最小公倍數
- 演算法分析——青蛙過河問題演算法
- 第六章 數學問題 ----------6.13 素數的篩法(第十萬零二個素數)
- 第六章 數學問題 -------- 6.2【Nim遊戲】高僧鬥法遊戲
- 第六章 數學問題 -------- 6.14 【快速冪】斐波那契數列
- 【機器學習之數學】03 有約束的非線性優化問題——拉格朗日乘子法、KKT條件、投影法機器學習優化
- matlab求解線性規劃問題Matlab
- 線性最小二乘問題
- 約瑟夫問題(丟手絹問題)
- LeetCode數學問題(Python)LeetCodePython
- 第六章 數學問題 -------- 6.4 演算法必備求和公式演算法公式
- 線性代數中的線性方程組方法
- 【問題記錄】—SignalR連線斷線重連SignalR
- 約瑟夫環問題 猴子選大王問題
- 約瑟夫問題
- vue 變數賦值同時改變的問題Vue變數賦值
- Matlab解決線性規劃問題Matlab
- 非線性規劃的經典例題--選址問題
- spring的問題-能耗、學習曲線Spring
- 洛谷題單指南-數學基礎問題-P1029 [NOIP2001 普及組] 最大公約數和最小公倍數問題
- P1516 青蛙的約會
- ArchLinux/Manjaro升級到6.9核心後的問題解決LinuxJAR
- python 來做數學問題Python
- 一名大專同學的四個問題
- 洛谷題單指南-數學基礎問題-P1403 [AHOI2005] 約數研究
- 線性同餘-常見語言編譯器引數編譯