题意:给你一个线段,问线段上有多少个整点.
分析:我们先把直线的一般式搞出来,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;
}
}