求一条线段上有多少个整点。
是道扩欧基础题,列出两点式方程,然后分四种情况讨论即可。但细节处理较多很容易写挫(某zzWA了十几发才过掉的)。
由于数据精度较小,浮点数比较没有用eps,直接==比较了。
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 typedef long long ll; 5 6 void exgcd(ll a,ll b,ll& x,ll& y,ll& g) { 7 if(!b)x=1,y=0,g=a; 8 else exgcd(b,a%b,y,x,g),y-=x*(a/b); 9 } 10 11 ll solve(double x1,double y1,double x2,double y2) { 12 if(x1>x2||(x1==x2&&y1>y2))swap(x1,x2),swap(y1,y2); 13 if(x1==x2&&y1==y2) { 14 if(x1==round(x1)&&x2==round(x2))return 1; 15 else return 0; 16 } else if(x1==x2) { 17 if(x1==round(x1))return floor(y2)-ceil(y1)+1; 18 else return 0; 19 } else if(y1==y2) { 20 if(y1==round(y1))return floor(x2)-ceil(x1)+1; 21 else return 0; 22 } else { 23 ll a=round((y2-y1)*100),b=round((x1-x2)*100),c=round((y2*x1-y1*x2)*100); 24 ll x,y,g; 25 exgcd(a,b,x,y,g); 26 if(c%g==0) { 27 x*=c/g; 28 ll bb=abs(b/g); 29 ll xl=ceil(x1),xr=floor(x2); 30 ll xll=x+(xl-x)/bb*bb; 31 ll xrr=x+(xr-x)/bb*bb; 32 if(xll<xl)xll+=bb; 33 if(xrr>xr)xrr-=bb; 34 return max(0ll,(xrr-xll)/bb+1); 35 } else return 0; 36 } 37 } 38 39 int main() { 40 ll T; 41 scanf("%lld",&T); 42 while(T--) { 43 double x1,y1,x2,y2; 44 scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); 45 printf("%lld\n",solve(x1,y1,x2,y2)); 46 } 47 return 0; 48 }
原文地址:https://www.cnblogs.com/asdfsag/p/10354003.html
时间: 2024-10-27 06:32:32