线性同余方程问题

线性同余方程

定义:形如 ax ≡ b (mod c)的方程被称为线性同余方程。

求解方法:线性同余方程可以通过两个定理求解得出答案:

定理1:

方程 ax + by = c 与方程 ax ≡ b ( mod c )是等价的,有整数解的充要条件是 gcd( a, b ) | c,即ab的最大公约数可以整除c 。

通过定理1我们可以通过exgcd求出一组解 x0,y0 ,然后两边同时除以gcd(a , b),再乘以c。然后就得到了方程 a*c*x0/gcdc(a , b) + b*c*y0/gcd(a, b) = c .这样我们就得出了方程的一个解。

定理2:

若 gcd(a, b) = 1,且 x0, y0 为方程 ax + by = c 的一组解,则该方程的任意解可表示为: x=x0 + bt, y= y0+ at , 且对任意整数 t 都成立。

根据定理2 ,我们可以求出方程所有的解 ,但在实际问题中,我们通常被要求求出一个最小整数解,也就是一个特解x , t = b/gcd(a, b), x = (x mod t +t) mod t 。即为最小整数解。

模板代码:

int ex_gcd(int a, int b, int& x, int& y)
{
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  }
  int d = ex_gcd(b, a % b, x, y);
  int temp = x;
  x = y;
  y = temp - a / b * y;
  return d;
}
bool liEu(int a, int b, int c, int& x, int& y) 		//将扩展欧几里德封装进函数。
{
  int d = ex_gcd(a, b, x, y);
  if (c % d != 0) return 0;
  int k = c / d;
  x *= k;
  y *= k;
  return 1;
}
if(!liEu(a,b,c,x,y))	cou<<"No answer"<<endl;
else					cout<<x<<" "<<y<<endl;
原文地址:https://www.cnblogs.com/StungYep/p/12252589.html