uva 11768

// 扩展欧几里得算法 
// 先求出一个解 再求出区间 [x1,x2]有几个整数符合条件
// 需要注意的是 水平和垂直2种情况的处理 还有正数和负数取整的细微差别
#include <iostream> #include <algorithm> #include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <string.h> using namespace std; #define MOD 1000000007 #define maxn 1000010 #define maxm 48010 #define LL long long LL ax,ay,bx,by; LL a,b,c; LL d,x,y; void extendGcd(LL a,LL b){ if(b==0){ d=a; x=1; y=0; }else{ extendGcd(b,a%b); LL t=x; x=y; y=t-a/b*y; } } LL lt(double p){ if(p>0){ LL x=p+0.05;x=x*10; LL y=(p+0.05)*10; if(x==y) return x/10; return x/10+1; } else{ return (LL)(p-0.05); } } LL rt(double p){ if(p>=0) return (LL)(p+0.05); else { LL x=p-0.05;x=x*10; LL y=(p-0.05)*10; if(x==y) return x/10; return x/10-1; } } LL get(double d){ if(d>=0) return (d+0.05)*10; else return (d-0.05)*10; } int main(){ int T; double x1,y1,x2,y2; LL ax,ay,bx,by; LL a,b,c; scanf("%d",&T); while(T--){ scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2); ax=get(x1);ay=get(y1); bx=get(x2);by=get(y2); if(ay==by){ if(ay%10) { printf("0\n");continue;} LL lx=lt(min(x1,x2)),rx=rt(max(x1,x2)); if(lx==rx&&ay%10){printf("0\n");continue;} printf("%lld\n",rx-lx+1); continue; } else if(ax==bx) { if(ax%10) { printf("0\n");continue;} LL ly=lt(min(y1,y2)),ry=rt(max(y1,y2)); if(ly==ry&&ax%10){printf("0\n");continue;} printf("%lld\n",ry-ly+1); continue; } a=(ay-by)*10; b=(bx-ax)*10; c=(bx-ax)*ay-(by-ay)*ax; extendGcd(a,b); if(c%d!=0){printf("0\n");continue;} x=x*(c/d); LL m=b/d; LL lx=lt(min(x1,x2)),rx=rt(max(x1,x2)); if(m<0) m=-m; x=x-(x-lx)/m*m; x-=m; while(x<lx) x+=m; LL k=(rx-x)/m; while(x+k*m<=rx) k++; printf("%lld\n",k); } return 0; }

 

你可能感兴趣的:(uva)