问题引入:直线上的点
求直线
ax
a
x
+
by
b
y
+ c = 0上有多少个整数点(x,y)满足
x
x
[
x1
x
1
,
x2
x
2
],
y
y
[
y1
y
1
,
y2
y
2
]。
分析:
在解决这个问题之前,首先学习扩展欧几里德算法——找一对整数
(x,y)
(
x
,
y
)
,使得
ax+by
a
x
+
b
y
=
gcd(a,b)
g
c
d
(
a
,
b
)
。
注意这里的
x和y
x
和
y
不一定是正数,也可能是负数或者是0,。例如,
gcd(6,15)
g
c
d
(
6
,
15
)
= 3,6*3 - 15*1 = 3,其中
x
x
= 3, = 1。这个方程还有其他解,如
x
x
= - 2, = 1。
下面是扩展欧几里德算法的程序:
void ext_gcd(int a, int b, int &d, int &x, int &y)
{
if(!b) {d = a;x = 1; y = 0;}
else {ext_gcd(b,a%b,d,y,x);y -= x*(a/b);}
}
证明
(证明过程参考自百度百科)
原式: ax+by=gcd(a,b) a x + b y = g c d ( a , b ) (假设a≥b)
当
b=0
b
=
0
时有
gcd(a,b)=a
g
c
d
(
a
,
b
)
=
a
,此时
x=1,y=0
x
=
1
,
y
=
0
;
当
b≠0
b
≠
0
时,根据欧几里得定理
gcd(a,b)=gcd(b,a
g
c
d
(
a
,
b
)
=
g
c
d
(
b
,
a
%
b)
b
)
可得
ax+by=gcd(a,b)=gcd(b,a
a
x
+
b
y
=
g
c
d
(
a
,
b
)
=
g
c
d
(
b
,
a
%
b)=bx′+(a
b
)
=
b
x
′
+
(
a
%
b)y′
b
)
y
′
,即
ax+by=bx′+(a
a
x
+
b
y
=
b
x
′
+
(
a
%
b)y′=bx′+(a−b∗⌊a/b⌋)y′
b
)
y
′
=
b
x
′
+
(
a
−
b
∗
⌊
a
/
b
⌋
)
y
′
移项得
ax+by=bx′+(a
a
x
+
b
y
=
b
x
′
+
(
a
%
b)y′=ay′+b(x′−⌊a/b⌋y′)
b
)
y
′
=
a
y
′
+
b
(
x
′
−
⌊
a
/
b
⌋
y
′
)
根据恒等定理,有
证毕
上面求出 ax+by=gcd(a,b) a x + b y = g c d ( a , b ) 的一组解 (x0,y0) ( x 0 , y 0 ) ,那么其他解呢?
任取另外一组解 (x,y) ( x , y ) ,则 ax0+by0=ax+by a x 0 + b y 0 = a x + b y (他们都等于 gcd(a,b) g c d ( a , b ) );
变形得: a(x0−x)=b(y0−y) a ( x 0 − x ) = b ( y 0 − y )
假设 gcd(a,b)=g g c d ( a , b ) = g ,
方程左右同时除以g,得: a′(x0−x)=b′(y0−y) a ′ ( x 0 − x ) = b ′ ( y 0 − y )
其中 a′=ag a ′ = a g , b′=bg b ′ = b g
这里 a′ a ′ , b′ b ′ 互素,因此 x0−x x 0 − x 一定是 b′ b ′ 的倍数, y0−y y 0 − y 一定是 a′ a ′ 的倍数;
x0−x=kb′ x 0 − x = k b ′ ;
y−y0=ka′ y − y 0 = k a ′ ;
所以得出结论:
假设a,b,c为任意整数。若方程 ax+by=c a x + b y = c 的一组解为 (x0,y0) ( x 0 , y 0 ) ,则它的任意常数解都可以写成 (x0+kb′,y0−ka′) ( x 0 + k b ′ , y 0 − k a ′ ) ,其中 a′=agcd(a,b) a ′ = a g c d ( a , b ) , b′=bgcd(a,b) b ′ = b g c d ( a , b ) , k k 取任意整数。
当是 g g 的倍数时的一组解是 (x0cg,y0cg) ( x 0 c g , y 0 c g ) ;
当 c c 不是是的倍数时无整数解。