问题:
求直线ax+by=c上有多少个整数点(x,y)满足x∈[x1,x2],y∈[y1,y2]。
分析:
为了解决这个问题,我们需要学习扩展欧几里得算法。我们知道欧几里得算法是求gcd(a,b)的,而扩展欧几里得算法则是求ax+by=gcd(a,b)时x和y的一组解。
不多说,直接把代码贴上:
void exgcd(int a,int b,int&d,int&x,int&y){
if(!b){d=a;x=1;y=0;}
else{exgcd(b,a%b,d,y,x);y-=x*(a/b);}
}
上面的代码求出了一组解,那么其它解呢?
设求出的解为(x1,y1),另一组解为(x2,y2),则ax1+by1=ax2+by2,变形得a(x1-x2)=b(y2-y1)。代码还求出gcd(a,b)=d,两边同时除以d,则a’(x1-x2)=b’(y2-y1),其中a’=a/d,b’=b/d。不难得出x1-x2是b’的整数倍。设倍数为k,可以计算得y2-y1=ka’。可以得出如下结论:
设a,b,c为任意整数,若方程ax+by=c的一个解是(x,y),则任意整数解都可以表示为(x+kb’,y-ka’),其中a’=a/gcd(a,b),b’=b/gcd(a,b),k取任意整数。
注意:在c不是gcd(a,b)的倍数时无解
举两个例子,自行验证一下:
例1:6x+15y=9,代码求出6 * (-2)+15 * 1=3,两边同时乘3得6 * (-6)+15 * 3=9,所以x=-6,y=3时6x+15y=9。
例2:6x+15y=8,因为gcd(6,15)=3,不是8的倍数,无解。
有如下结论:
设a,b,c为任意整数,g=gcd(a,b),方程ax+by=g时的一组解为(x,y),则当c是g的倍数时ax+by=c的一组解是(x * c/g,y * c/g),当c不是g的倍数时无解。
代码如下:
注:如果题目要求的直线方程是ax+by+c=0,那么只需要在for的开头输入c后加一句c=-c即可,因为它移项后可以变成ax+by=-c。
#include <iostream>
#include <cmath>
using namespace std;
void gcd(int a,int b,int&d,int&x,int&y){
if(!b){d=a;x=1;y=0;}
else{gcd(b,a%b,d,y,x);y-=x*(a/b);}
}
int main(){
int a,b,c,d,x,y,x0,x1,y0,y1;
for(int o_o=0;cin>>a>>b>>c;o_o++){
cin>>x0>>x1>>y0>>y1;
if(o_o)cout<<endl;
gcd(a,b,d,x,y);
if(c%d){cout<<"No answer."<<endl;continue;}
int bei=c/d;
a/=d;b/=d;x*=bei;y*=bei;
int mink=max(ceil (1.0*(x0-x)/b),ceil (1.0*-(y1-y)/a));
int maxk=min(floor(1.0*(x1-x)/b),floor(1.0*-(y0-y)/a));
if(maxk<mink)cout<<"No answer."<<endl;
else if(maxk==mink) cout<<"There is 1 answer."<<endl;
else cout<<"There are "<<(maxk-mink+1)<<" answers."<<endl;
for(int k=mink;k<=maxk;k++)
cout<<"("<<x+k*b<<","<<y-k*a<<")"<<endl;
}
return 0;
}
输入样例1:
1 2 3
-10 10 -10 10
6 15 8
-10 10 -10 10
输出样例1:
There are 10 answers.
(-9,6)
(-7,5)
(-5,4)
(-3,3)
(-1,2)
(1,1)
(3,0)
(5,-1)
(7,-2)
(9,-3)
No answer.
输入样例2:
6 15 9
-20 20 -20 20
6 15 9
1 1 1 1
6 15 9
-1 -1 1 1
输出样例2:
There are 8 answers.
(-16,7)
(-11,5)
(-6,3)
(-1,1)
(4,-1)
(9,-3)
(14,-5)
(19,-7)
No answer.
There is 1 answer.
(-1,1)
输入样例3:
99 78 14
-50 50 -50 50
99 78 15
-50 50 -50 50
输出样例3:
No answer.
There are 3 answers.
(-29,37)
(-3,4)
(23,-29)