sgu 106(扩展欧几里德算法)

终于知道自己错哪了。。。

下面把自己的做法再分析一下。感觉扩展欧几里德算法经过这题以后比较熟悉了。

首先 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 }

 

posted @ 2013-03-09 17:26  Missa  阅读(380)  评论(0编辑  收藏  举报