lightoj 1306 - Solutions to an Equation 扩展的欧几里得

思路:看题就知道用扩展的欧几里得算法做!!!

首先我们可以求出ax+by=gcd(a,b)=g的一个组解(x0,y0).而要使ax+by=c有解,必须有c%g==0.

继而可以得到ax+by=c的一个组解x1=c*x0/g , y1=c*y0/g。

这样可以得到ax+by=c的通解为:

                  x=x1+b*t;

                  y=y1-a*t;

再就是要注意符号问题!!!

代码如下:

 

 1 #include<cstdio>

 2 #include<algorithm>

 3 #define ll long long

 4 using namespace std;  5 ll gcd_extend(ll a,ll b,ll &x,ll &y)  6 {  7     if(b==0){  8         x=1;y=0;  9         return a; 10  } 11     else{ 12         ll g=gcd_extend(b,a%b,x,y); 13         ll t=x; 14         x=y; 15         y=t-a/b*y; 16         return g; 17  } 18 } 19 int sign(ll a) 20 { 21     if(a==0) return 0; 22     return a>0?1:-1; 23 } 24 ll ceil(ll a,ll b)  //向上取整,注意符号

25 { 26     int s=sign(a)*sign(b); 27     return b/a+(b%a!=0&&s>0); 28 } 29 ll floor(ll a,ll b)  //向下取整,注意符号

30 { 31     int s=sign(a)*sign(b); 32     return b/a-(b%a!=0&&s<0); 33 } 34 int main() 35 { 36     int t,ca=0; 37  ll a,b,c,x1,x2,y1,y2,x,y; 38     scanf("%d",&t); 39     while(t--){ 40         scanf("%lld%lld%lld%lld%lld%lld%lld",&a,&b,&c,&x1,&x2,&y1,&y2); 41         printf("Case %d: ",++ca); 42         if(a==0&&b==0){ 43             if(c==0) printf("%lld\n",(x2-x1+1)*(y2-y1+1)); 44             else printf("0\n"); 45             continue; 46  } 47         if(a==0){ 48             if(c%b!=0){ 49                 printf("0\n"); 50                 continue; 51  } 52             ll tt=-c/b; 53             if(y1<=tt&&tt<=y2) printf("%lld\n",x2-x1+1); 54             else printf("0\n"); 55             continue; 56  } 57         if(b==0){ 58             if(c%a!=0){ 59                 printf("0\n"); 60                 continue; 61  } 62             ll tt=-c/a; 63             if(x1<=tt&&tt<=x2) printf("%lld\n",y2-y1+1); 64             else printf("0\n"); 65             continue; 66  } 67         ll g=gcd_extend(a,b,x,y); 68         if(c%g!=0){ 69             printf("0\n"); 70             continue; 71  } 72         if(sign(g)*sign(b)<0) swap(x1,x2); 73         ll l1=ceil(b,g*x1+c*x); 74         ll l2=floor(b,g*x2+c*x); 75         if(sign(-a)*sign(g)<0) swap(y1,y2); 76         ll r1=ceil(-a,g*y1+c*y); 77         ll r2=floor(-a,g*y2+c*y); 78         l1=max(l1,r1); 79         r1=min(l2,r2); 80         if(l1>r1) printf("0\n"); 81         else printf("%lld\n",r1-l1+1); 82  } 83     return 0; 84 }
View Code

 

 

 

你可能感兴趣的:(IO)