题意:
给定两个整点,求这段线段之间跨过的整点的个数
思路:
1,再纸上画一下就可以猜到了
2,证明一下:
设线段的两个端点为 (x1, y1) 和 (x2, y2)
我们都知道,要是这个线段经过某个整点(a,b)的话,我令 dx = (a - x1), dy = (b - y1);必定有 dy / dx = (x2 - x1) / (y2 - y1) ①, 因为要满足相同的斜率
还能推出: dy / ( y2 - y1 ) = dx / (x2 - x1)—— ②;
假设这个整点是从(x1, y1)开始的第一个整点,然后我把这个 dx dy 叫做整点元(自己瞎取的),而且这个线段经过的所有两两相邻的整点,x y 差值也满足 dx dy;
要求经过整点的个数,就要求(x2 - x1) 和 (y2 - y1)的最大公约数 gcd , (x2 - x1) / gcd 和 (y2 - y1)/ gcd 就是我说的整点元 dx dy;
最后结果加上(x1, y1)这个点,
注意数据范围
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<set>
#include<queue>
#include<stack>
#include<map>
#define PI acos(-1.0)
#define in freopen("in.txt", "r", stdin)
#define out freopen("out.txt", "w", stdout)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e6 + 7, maxd = 20 + 7, mod = 1e9 + 7;
const int INF = 0x7f7f7f7f;
int T;
ll gcd(ll a, ll b) {
return b == 0 ? a : gcd(b, a%b);
}
int main() {
int T;
scanf("%d", &T);
for(int tt = 1; tt <= T; ++tt) {
ll a, b, c, d;
scanf("%lld %lld %lld %lld", &a, &b, &c, &d);
ll ans = gcd( abs(a-c), abs(b-d) );
printf("Case %d: %lld\n", tt, ans+1);
}
return 0;
}