lightoj 1306

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

首先我们可以求出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
",(x2-x1+1)*(y2-y1+1));
44             else printf("0
");
45             continue;
46         }
47         if(a==0){
48             if(c%b!=0){
49                 printf("0
");
50                 continue;
51             }
52             ll tt=-c/b;
53             if(y1<=tt&&tt<=y2) printf("%lld
",x2-x1+1);
54             else printf("0
");
55             continue;
56         }
57         if(b==0){
58             if(c%a!=0){
59                 printf("0
");
60                 continue;
61             }
62             ll tt=-c/a;
63             if(x1<=tt&&tt<=x2) printf("%lld
",y2-y1+1);
64             else printf("0
");
65             continue;
66         }
67         ll g=gcd_extend(a,b,x,y);
68         if(c%g!=0){
69             printf("0
");
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
");
81         else printf("%lld
",r1-l1+1);
82     }
83     return 0;
84 }
View Code
原文地址:https://www.cnblogs.com/xin-hua/p/3372910.html