UVA - 11768 Lattice Point or Not (扩展欧几里得)

求一条线段上有多少个整点。

是道扩欧基础题,列出两点式方程,然后分四种情况讨论即可。但细节处理较多很容易写挫(某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 }

猜你喜欢

转载自www.cnblogs.com/asdfsag/p/10354003.html
今日推荐