http://hi.baidu.com/lycanlancelot/item/8ad98b4aefeef8a4de2a9f53
方程ax+by+c=0; 问有多少对x,y. 满足 x1<=x<=x2, y1<=y<=y2
ax+by=-c.
c=-c,后, 扩展欧几里得求一下,x,y;
x,y满足 ax+by=gcd(a,b);
x*=c/gcd(a,b);
y*=c/gcd(a,b);后
x,y满足 ax+by=c;
通解:
x0=x+k*b/gcd(a,b);
y0=y-k*a/gcd(a,b);
然后判断在范围中的对数。。
p=b/gcd()a,b;
x1<= x+k*p <=x2;
(x1-x)/p <= k <= (x2-x)/p;
这里(x1-x)/p, 比如当(x1-x)<=0时,假如是-9,p=2, 那么值为 -9/2 = -4.. (-9<=k*2 -4<=k;) 满足条件。。
假如是9,p=2, 那么值为9/2=4, (9<=k*2 4<=k) 不满足条件,应该值为5..
所以要特判一下边界问题,然后取交集。。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<math.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll __int64
ll x,y;
ll exgcd(ll a,ll b)
{
if(b==0)
{
x=1,y=0;
return a;
}
ll gcd=exgcd(b,a%b);
ll t=x;
x=y;
y=t-a/b*y;
return gcd;
}
ll mod(ll a,ll b)
{
if(a>=0)
return a%b; //a%b,结果正负,只和a的正负有关
else
return a%b+abs(b); //b可能为负数。
}
int main()
{
ll a,b,c,x1,x2,y1,y2;
ll sum=0;
cin>>a>>b>>c>>x1>>x2>>y1>>y2;
c=-c;
if(a==0&&b==0)
{
if(c==0)
sum=(x2-x1+1)*(y2-y1+1);
}
else if(a==0)
{
if(c/b>=y1&&c/b<=y2&&c%b==0)
sum=x2-x1+1;
}
else if(b==0)
{
if(c/a<=x2&&c/a>=x1&&c%a==0)
sum=y2-y1+1;
}
else
{
ll g=exgcd(a,b);
if(c%g==0)
{
x*=c/g;
y*=c/g;
ll p=b/g,q=a/g;
ll lx=(x1-x>0&&(x1-x)%p!=0)?((x1-x)/p+1):((x1-x)/p);
ll rx=(x2-x<0&&(x2-x)%p!=0)?((x2-x)/p-1):((x2-x)/p);
ll ly=(y-y2>0&&(y-y2)%q!=0)?((y-y2)/q+1):((y-y2)/q);
ll ry=(y-y1<0&&(y-y1)%q!=0)?((y-y1)/q-1):((y-y1)/q);
if(lx>rx) swap(lx,rx);
if(ly>ry) swap(ly,ry);
if(rx>=ly&&ry>=lx)
{
ll mx=max(lx,ly);
ll mn=min(rx,ry);
sum=mn-mx+1;
}
}
}
cout<<sum<<endl;
//system("pause");
}