LightOJ - 1077 How Many Points? 最大公约数(线段经过整点个数与gcd 证明)

7 篇文章 0 订阅

题意:

给定两个整点,求这段线段之间跨过的整点的个数

思路:

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;
}




  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值