http://acm.sgu.ru/problem.php?contest=0&problem=106
题意:
给你一个 ax+by+c = 0的方程, 然后分别给你x、y的区间[x1 , x2] , [y1 , y2] 问你x、y都在给
定区间内的解一共有多少组。
思路:
利用扩张欧几里得算法求出:ax + by = gcd(a ,b) = d 的一组解(x0 ,y0),则原方程有解的条件是
d | c,原方程的解是:x0*c/d + i*b/d , y0 - i*a/d ; 最后只要通过简单的判断就可以得出问题的解。
代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
typedef __int64 LL ;
LL a,b,c,x1,yy1,x2,yy2 ;
LL ex_gcd(LL a ,LL b, LL& x, LL& y){
if(b == 0){
x = 1 ; y = 0 ;
return a ;
}
LL d = ex_gcd(b,a%b,x,y) ;
LL t = x ;
x = y ;
y = t - a/b*y ;
return d ;
}
LL MAX(LL a ,LL b){
return a > b ? a : b ;
}
LL MIN(LL a, LL b){
return a > b ? b : a ;
}
int main(){
LL x ,y,ans,res_x ,res_y,low_t ,high_t ;
LL low_t1 , high_t1 ;
LL aa, bb ;
while(scanf("%I64d%I64d%I64d",&a,&b,&c) == 3){
scanf("%I64d%I64d%I64d%I64d",&x1,&x2,&yy1,&yy2) ;
c = -c ;
if(a == 0 && b==0){
if(c != 0){
printf("0\n");
}
else{
ans = (x2-x1+1)*(yy2-yy1+1) ;
printf("%I64d\n",ans);
}
continue ;
}
else if(a == 0){
if(c % b != 0){
printf("0\n");
}
else{
ans = x2 - x1 + 1 ;
printf("%I64d\n",ans);
}
continue ;
}
else if(b == 0){
if(c%a != 0){
printf("0\n");
}
else{
ans = yy2 - yy1 + 1 ;
printf("%I64d\n",ans);
}
continue ;
}
LL d = ex_gcd(a,b,x,y) ;
if( c%d != 0 ){
printf("0\n"); continue ;
}
ans = 0 ;
res_x = (c)/d * x ;
res_y = (c)/d * y ;
b /= d ;
a /= d ;
if(b>0){
low_t = ceil( (x1 - res_x )*1.0/b ) ;
high_t = floor( (x2-res_x)*1.0/b ) ;
if(a > 0){
low_t1 = ceil( (res_y-yy2)*1.0/a) ;
high_t1 = floor( (res_y-yy1)*1.0/a ) ;
}
else{
a = -a ;
low_t1 = ceil( (yy1 - res_y)*1.0/a ) ;
high_t1 = floor( (yy2-res_y)*1.0/a ) ;
}
aa = MAX( low_t, low_t1);
bb = MIN( high_t, high_t1);
if(aa > bb){
;
}
else{
ans += (bb-aa+1) ;
}
}
else{
b = -b ;
low_t = ceil( (res_x -x2)*1.0/b );
high_t = floor( (res_x - x1)*1.0 / b) ;
if(a > 0){
low_t1 = ceil( (res_y-yy2)*1.0/a) ;
high_t1 = floor( (res_y-yy1)*1.0/a ) ;
}
else{
a = -a ;
low_t1 = ceil( (yy1 - res_y)*1.0/a ) ;
high_t1 = floor( (yy2-res_y)*1.0/a ) ;
}
aa = MAX( low_t, low_t1);
bb = MIN( high_t, high_t1);
if(aa > bb){
;
}
else{
ans += (bb-aa+1) ;
}
}
printf("%I64d\n",ans);
}
return 0 ;
}