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 ; }