终于知道自己错哪了。。。
下面把自己的做法再分析一下。感觉扩展欧几里德算法经过这题以后比较熟悉了。
首先 ax+by=gcd(a,b)可以由exgcd求出。
设 g=gcd(a,b);
然后对于开始的那个方程 a*x+b*y=c;可知,如果c%gcd(a,b) !=0 那么无解。
否则由a*x0+b*y0=gcd(a,b)--->a*x0*(c/g)+b*y0*(c/g)=c;
得到ax+by=c的一个特解Xt=x0*(c/g),Yt=y0*(c/g);
接下来求所有满足ax+by=c的x,y解。
开始的时候我列出了一个式子:a*Xt+n*a*b+b*Yt-n*a*b=c显然是满足的。然后推出 a*(Xt+n*b)+b*(Yt-n*a)=c--->然后解出这题的lx,rx,ly,ry;感觉好像对的。其实错大了。因为这里的 n*b 和n*a可以分成更小的值。换句话说就是 原式可以写成 a*Xt+n*lcm(a,b)+b*Yt-n*lcm(a,b)=c; 求出 a*(Xt+n*b/gcd(a,b))+b*(Yt-n*a/gcd(a,b))=c;这里的间距才是最小的间距。。原来那样会省略掉很多值。。还是太水的开始没搞懂。。囧。
1 // File Name: 106.cpp 2 // Author: Missa 3 // Created Time: 2013/3/5 星期二 16:42:19 4 5 #include<iostream> 6 #include<cstdio> 7 #include<cstring> 8 #include<algorithm> 9 #include<cmath> 10 #include<queue> 11 #include<stack> 12 #include<string> 13 #include<vector> 14 #include<cstdlib> 15 #include<map> 16 #include<set> 17 using namespace std; 18 #define CL(x,v) memset(x,v,sizeof(x)); 19 #define R(i,st,en) for(int i=st;i<en;i++) 20 #define ll long long 21 22 ll a,b,X,Y; 23 ll exgcd(ll a,ll b,ll &x,ll &y) 24 { 25 ll d,tmp; 26 if(b==0) 27 { 28 x=1; 29 y=0; 30 return a; 31 } 32 d=exgcd(b,a%b,x,y); 33 tmp=x; 34 x=y; 35 y=tmp-a/b*y; 36 return d; 37 } 38 39 int main() 40 { 41 ll c,x1,y1,x2,y2; 42 while(~scanf("%I64d",&a)) 43 { 44 scanf("%I64d%I64d%I64d%I64d%I64d%I64d",&b,&c,&x1,&x2,&y1,&y2); 45 c=-c; 46 if(a==0 && b==0) 47 { 48 if(c==0) 49 { 50 printf("%I64d\n",(x2-x1+1)*(y2-y1+1)); 51 } 52 else puts("0"); 53 continue; 54 } 55 else if(b==0) 56 { 57 if(c%a==0 && c/a>=x1 && c/a<=x2) 58 printf("%I64d\n",y2-y1+1); 59 else 60 puts("0"); 61 continue; 62 } 63 else if(a==0) 64 { 65 if(c%b==0 && c/b>=y1 && c/b<=y2) 66 printf("%I64d\n",x2-x1+1); 67 else 68 puts("0"); 69 continue; 70 } 71 ll g=exgcd(a,b,X,Y); 72 //cout<<"gcd="<<g<<endl; 73 if(c%g != 0) 74 puts("0"); 75 else 76 { 77 X=X*(c/g); 78 Y=Y*(c/g); 79 ll ans; 80 //这里 81 b/=g; 82 a/=g; 83 double Lx=(double)(x1-X)/b; 84 double Rx=(double)(x2-X)/b; 85 double Ly=(double)(Y-y2)/a; 86 double Ry=(double)(Y-y1)/a; 87 if(Lx>Rx)swap(Lx,Rx); 88 if(Ly>Ry)swap(Ly,Ry); 89 ans=min((ll)floor(Rx),(ll)floor(Ry))-max((ll)ceil(Lx),(ll)ceil(Ly))+1; 90 if(ans<0) ans=0; 91 printf("%I64d\n",ans); 92 } 93 } 94 return 0; 95 }