codevs 1213 解的个数
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 黄金 Gold
题目描述 Description
已知整数x,y满足如下面的条件:
ax+by+c = 0
p<=x<=q
r<=y<=s
求满足这些条件的x,y的个数。
输入描述 Input Description
第一行有一个整数n(n<=10),表示有n个任务。n<=10
以下有n行,每行有7个整数,分别为:a,b,c,p,q,r,s。均不超过108。
输出描述 Output Description
共n行,第i行是第i个任务的解的个数。
样例输入 Sample Input
2
2 3 -7 0 10 0 10
1 1 1 -10 10 -9 9
样例输出 Sample Output
1
19
1 #include<iostream> 2 using namespace std; 3 #include<cstdio> 4 #include<cstring> 5 int n; 6 long long a,b,c,p,q,r,s; 7 void exgcd(int a,int b,int &x,int &y,int &gcd) 8 { 9 if(b==0) 10 { 11 x=1;y=0; 12 gcd=a; 13 return; 14 } 15 exgcd(b,a%b,x,y,gcd); 16 int t=x; 17 x=y; 18 y=t-(a/b)*y; 19 } 20 int main() 21 { 22 scanf("%d",&n); 23 while(n--) 24 { 25 cin>>a>>b>>c>>p>>q>>r>>s; 26 long long ans=0; 27 if(a==0&&b==0&&c==0)/*特判两种特殊的情况*/ 28 { 29 if(q>=p&&s>=r) 30 ans=(q-p+1)*(s-r+1);/*区间如果可以取到,就是区间内所有元素的个数*/ 31 cout<<ans<<endl; 32 continue; 33 } 34 if(a==0&&b==0&c!=0) 35 { 36 cout<<"0"<<endl; 37 continue; 38 } 39 int gcd,x,y; 40 /* if(a<b) swap(a,b);扩展欧几里得算法是不在乎a,b的大小的,但是如果交换了a,b,那么x,y的值也会互掉了,所以不能交换*/ 41 exgcd(a,b,x,y,gcd); 42 int k=(-1*c)/gcd; 43 x*=k;y*=k;/*这是真正的x,y的值,刚才求的是ax+by==gcd(a,b)的解*/ 44 int a0=a/gcd,b0=b/gcd; 45 for(int i=-1000000;i<=1000000;++i)/*一个可能的倍数范围*/ 46 { 47 if(x+i*b0<p||x+i*b0>q||y-i*a0<r||y-i*a0>s) continue; 48 if(a*(x+i*b0)+b*(y-i*a0)==(-1*c)) ans++;/*别忘记:i*b0,i*a0,一个是+,一个是-,而且,每次不是加a,b,而是加a/gcd(a,b)的值,只是满足这个关系的最小整数*/ 49 } 50 cout<<ans<<endl; 51 } 52 return 0; 53 }