Uva-11768 Lattice Point or Not(欧扩)

185 篇文章 0 订阅
50 篇文章 0 订阅

题意:给你一个线段,问线段上有多少个整点.


分析:我们先把直线的一般式搞出来,ax+by=c的形式,然后用欧扩求出直线一个整数点,设其横标为x,那么答案就是floor((x2-x)/b') - ceil((x1-x)/b') + 1. (x2 >= x1, b' = b/gcd(a,b)).


#include <bits/stdc++.h>
#define INF 1047483647
#define eps 1e-8
using namespace std;
typedef long long ll;
int n;
ll x,y;
double xl,yl,xt,yt;
void exgcd(ll a,ll b,ll &x,ll &y)
{
    if(!b) x=1,y=0;
    else
    {
        exgcd(b,a%b,y,x);
        y-=a/b*x;
    }
}
int main()
{
    scanf("%d",&n);
    while(n--)
    {
        scanf("%lf%lf%lf%lf",&xl,&yl,&xt,&yt);
        if(xl == xt)
        {
            if(xl != long(xl))
            {
                cout<<0<<endl;
                continue;
            }
            cout<<floor(max(yl,yt)) - ceil(min(yl,yt)) + 1<<endl;
            continue;
        }
        if(yl == yt)
        {
            if(yl != long(yl))
            {
                cout<<0<<endl;
                continue;
            }
            cout<<floor(max(xl,xt)) - ceil(min(xl,xt)) + 1<<endl;
            continue;
        }
        ll Xl = xl*10,Xt = xt*10,Yl = yl*10,Yt = yt*10;
        ll A = 10*(Yt-Yl),B = 10*(Xl- Xt),C = Xl*Yt - Yl*Xt;
        ll temp = __gcd(__gcd(A,B),C);
        A/=temp,B/=temp,C/=temp;
        ll d = abs(B/__gcd(A,B));
        if(C % __gcd(A,B))
        {
            cout<<0<<endl;
            continue;
        }
        exgcd(A,B,x,y);
        x *= C/__gcd(A,B);
        if(xl > xt) swap(xl,xt);
        cout<<floor((xt-x)/d) - ceil((xl-x)/d) + 1<<endl;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值