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 }

 

你可能感兴趣的:(算法)