题目大意
解题思路
(1) 当直线斜率存在时,格点数为
g
c
d
(
∣
x
2
−
x
1
∣
,
∣
y
2
−
y
1
∣
)
−
1
gcd(|x_2-x_1|, |y_2-y_1|) - 1
gcd(∣x2−x1∣,∣y2−y1∣)−1
(2) 当斜率不存在且
y
2
!
=
y
1
y_2 != y_1
y2!=y1时,格点数为
∣
y
2
−
y
1
∣
−
1
|y_2-y_1|-1
∣y2−y1∣−1
(3) 当斜率不存在且
y
2
=
y
1
y_2 = y_1
y2=y1时,格点数为0.
证明如下:
a
a
a: 当斜率不存在时,很容易得出(2),(3)结论。
b
b
b: 当斜率存在时。 斜率为
y
2
−
y
1
x
2
−
x
1
\frac{y_2-y_1}{x_2- x_1}
x2−x1y2−y1。当横坐标增加
Δ
x
\Delta x
Δx, 则对应纵坐标增加
Δ
x
y
2
−
y
1
x
2
−
x
1
\Delta x \frac{y_2-y_1}{x_2- x_1}
Δxx2−x1y2−y1, 很明显,要格点最多,且每次增加都落在格点上,我们希望 (1)每次增加的距离
Δ
x
\Delta x
Δx要尽量小。(2)
Δ
x
\Delta x
Δx和
Δ
x
y
2
−
y
1
x
2
−
x
1
\Delta x \frac{y_2-y_1}{x_2- x_1}
Δxx2−x1y2−y1 都是整数。
- 直接令 Δ x \Delta x Δx为整数。
- 对 Δ x y 2 − y 1 x 2 − x 1 \Delta x \frac{y_2-y_1}{x_2- x_1} Δxx2−x1y2−y1 : 有 Δ x y 2 − y 1 x 2 − x 1 = Δ x y 2 − y 1 / g c d x 2 − x 1 / g c d \Delta x \frac{y_2-y_1}{x_2- x_1} = \Delta x \frac{y_2-y_1/gcd}{x_2-x_1/gcd} Δxx2−x1y2−y1=Δxx2−x1/gcdy2−y1/gcd.其中 g c d gcd gcd为分子分母最大公约数。要使其为整数,则 Δ x \Delta x Δx能够整除 x 2 − x 1 g c d \frac{x_2-x_1}{gcd} gcdx2−x1.而要使 Δ x \Delta x Δx最小,则其就等于 x 2 − x 1 g c d \frac{x_2-x_1}{gcd} gcdx2−x1.
- 因此要格点最多,且每次增加都落在格点上,则 Δ x = x 2 − x 1 g c d \Delta x = \frac{x_2-x_1}{gcd} Δx=gcdx2−x1, 对应的格点数目为 x 2 − x 1 Δ x − 1 = g c d − 1 \frac{x_2-x_1}{\Delta x} - 1=gcd-1 Δxx2−x1−1=gcd−1
- 得证。
代码
#include<iostream>
using namespace std;
int abs(int x)
{
if(x < 0)
return -x;
return x;
}
int gcd(int a, int b)
{
if(a < b)
swap(a, b);
if(b == 0)
return a;
return gcd(b, a%b);
}
int main()
{
int x1,y1,x2,y2;
cin >> x1 >> y1 >> x2 >> y2;
if(x1 == x2)
{
if(y1 == y2)
cout << 0 << endl;
else
cout << abs(y1-y2)-1 << endl;
}
else
{
cout << gcd(abs(y1-y2), abs(x1-x2)) - 1 << endl;
}
return 0;
}