A - Solutions to an Equation
You have to find the number of solutions of the following equation:
Ax + By + C = 0
Where A, B, C, x, y are integers and x1 ≤ x ≤ x2 and y1 ≤ y ≤ y2.
Input
Input starts with an integer T (≤ 10000), denoting the number of test cases.
Each case starts with a line containing seven integers A, B, C, x1, x2, y1, y2 (x1 ≤ x2, y1 ≤ y2). The value of each integer will lie in the range [-108, 108].
Output
For each case, print the case number and the total number of solutions.
Sample Input
5
1 1 -5 -5 10 2 4
-10 -8 80 -100 100 -90 90
2 3 -4 1 7 0 8
-2 -3 6 -2 5 -10 5
1 8 -32 0 0 1 10
Sample Output
Case 1: 3
Case 2: 37
Case 3: 1
Case 4: 2
Case 5: 1
分析:
显然用扩展欧几里得求整数解,先贴一下大佬求解过程:
扩展欧几里德算法证明过程:
如何求其他解;
还要注意用不等式求解时,要讨论正负号,为负数时不等式方向会改变,同小取小,同大取大
同时还要注意a==0&&b==0,a==0&&b!=0,a!=0&&b==0这三种情况要单独讨论
AC code:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
void exgcd(ll a,ll b,ll& d,ll &x,ll &y)
{
if(!b){
d=a,x=1,y=0;
}
else
{
exgcd(b,a%b,d,y,x);
y-=x*(a/b);
}
}
int main()
{
int t;
cin>>t;
ll a,b,c,x1,y1,x2,y2;
int cas=0;
while(t--)
{
ll x,y,gcd;
cin>>a>>b>>c>>x1>>x2>>y1>>y2;
c=-c;//变为扩展欧几里得方程的形式
cas++;
cout<<"Case "<<cas<<": ";
ll ans=0;
///单独讨论特殊情况
if(a==0&&b==0)
{
if(c==0)
cout<<(x2-x1+1)*(y2-y1+1)<<endl;
else
cout<<0<<endl;
continue;
}
else if(a==0&&b!=0)
{
if(c%b==0)
{
ll tmp=c/b;
if(y1<=tmp&&tmp<=y2)
ans=x2-x1+1;
}
cout<<ans<<endl;
continue;
}
else if(a&&b==0)
{
if(c%a==0)
{
ll tmp=c/a;
if(x1<=tmp&&tmp<=x2)
ans=y2-y1+1;
}
cout<<ans<<endl;
continue;
}
exgcd(a,b,gcd,x,y);
if(c%gcd)
{
cout<<0<<endl;
continue;
}///如果c不是gcd的倍数则无整数解
ll x0=x*c/gcd;
ll y0=y*c/gcd;
ll b1=b/gcd;
ll a1=a/gcd;
ll tx1,tx2,ty1,ty2;
if(b*gcd>=0)
{
tx1=ceil(1.0*(x1-x0)/b1);//左边界向右取整
tx2=floor(1.0*(x2-x0)/b1);//右边界向左取整
}
else
{
tx1=ceil(1.0*(x2-x0)/b1);
tx2=floor(1.0*(x1-x0)/b1);
}
if(a*gcd>=0)
{
ty1=ceil(1.0*(y0-y2)/a1);
ty2=floor(1.0*(y0-y1)/a1);
}
else
{
ty1=ceil(1.0*(y0-y1)/a1);
ty2=floor(1.0*(y0-y2)/a1);
}
ll l=max(tx1,ty1);
ll r=min(tx2,ty2);
if(l>r)
cout<<0<<endl;
else
cout<<r-l+1<<endl;
}
return 0;
}