106. 等式
时间限制:0.5s
内存限制:4096KB
对于等式ax+by+c=0,给出a,b,c,x1,x2,y1,y2,你必须要确定有多少个满足下面条件的整数对(x,y)存在,x1<=x<=x2,y1<=y<=y2。
输入:
包含整数a,b,c,x1,x2,y1,y2,所有数的绝对值都不大于
108
输出:
输出结果个数。
================================华丽的分割线 ================================
首先,抱歉,四天前就翻译好了,现在才上交题解!实在没办法啊,好几个原因,第一,个人好奇心太强了!扩展欧几里德算法的原理一定要看懂,知道怎么证明才想动手,但是实在抱歉哈,还是有一些没看懂的地方……第二,SGU不给数据,错了不知道从哪里查起,确实麻烦!第三,SGU的怪编译器,在:
long long i;
scanf("%lld", &i);
这样它就是不接受,第一个点就WA,但是按照网上一个人的代码,改成:
long long i;
scanf("%I64d", &i);
就AC了……无语吧,GCC我真没印象有I64d这玩意儿,就算有,是我才学疏浅,但是,但是……lld分明是C99中实用的,不信去《C Primer Plus》里去看!!
================================华丽的分割线 ================================
算法分析,这题用到了
扩展欧几里德原理。
关于扩展的分析看上面的链接吧,接着简单分析一下,题意很清晰!直接贴思路:
关于扩展的分析看上面的链接吧,接着简单分析一下,题意很清晰!直接贴思路:
- 当a==0,b==0时,c若等于0则答案就是题目的范围内的所有整数点。
- 若a==0时,by=-c,c是b的倍数,且在范围内就有答案,否则0个。
- 当b==0时,ax=-c,c是a的倍数,且在范围内就有答案,否则0个。
- 如果上面的条件都不符合,则使用扩展欧几里德算法。
#include
<
stdio.h
>
#include < stddef.h >
#include < stdlib.h >
long long a, b, c;
long long extgcd( long long a, long long b, long long * x, long long * y)
{
int t, s;
if (b == 0 ){
* x = 1 ;
* y = 10 ;
return a;
}
t = extgcd(b, a % b, x, y);
s = * x;
* x = * y;
* y = s - a / b * ( * y);
return t;
}
#define max(a, b) ((a)>(b)?(a):(b))
#define min(a, b) ((a)<(b)?(a):(b))
#define swap(a, b) (a)^=(b);(b)^=(a);(a)^=(b);
int main( int argc, char ** argv)
{
long long x1, x2;
long long y1, y2;
long long x, y, t;
long long ans = 0 ;
//
scanf ( " %I64d%I64d%I64d " , & a, & b, & c);
c = - c;
scanf ( " %I64d%I64d%I64d%I64d " , & x1, & x2, & y1, & y2);
// scanf("%d%d%d", &a, &b, &c);
// scanf("%d%d", &x1, &x2);
// scanf("%I64d%d", &y1, &y2);
// c = -c;
if (a == 0 && b == 0 ){
if (c == 0 ){
ans = (x2 - x1 + 1 ) * (y2 - y1 + 1 );
}
} else if (a == 0 ){
if (c % b == 0 && c / b >= y1 && c / b <= y2){
ans = x2 - x1 + 1 ;
}
} else if (b == 0 ){
if (c % a == 0 && c / a >= x1 && c / a <= x2){
ans = y2 - y1 + 1 ;
}
} else {
t = extgcd(a, b, & x, & y);
if (c % t == 0 ){
x *= c / t;
y *= c / t;
// printf("%d %d\n", x, y);
long long lx, ly;
long long rx, ry;
lx = (x1 <= x || (x1 - x) * t % b == 0 ) ? ((x1 - x) * t / b) : ((x1 - x) * t / b + 1 );
rx = (x2 >= x || (x2 - x) * t % b == 0 ) ? ((x2 - x) * t / b) : ((x2 - x) * t / b - 1 );
ly = (y1 <= y || (y - y1) * t % a == 0 ) ? ((y - y1) * t / a) : ((y - y1) * t / a - 1 );
ry = (y2 >= y || (y - y2) * t % a == 0 ) ? ((y - y2) * t / a) : ((y - y2) * t / a + 1 );
if (lx > rx){
swap(lx, rx);
}
if (ly > ry){
swap(ly, ry);
}
// printf("%d %d %d %d\n", lx, rx, ly, ry);
if (ry >= lx && rx >= ly){
ans = min(rx, ry) - max(lx, ly) + 1 ;
}
}
}
printf( " %I64d\n " , ans);
return 0 ;
}
#include < stddef.h >
#include < stdlib.h >
long long a, b, c;
long long extgcd( long long a, long long b, long long * x, long long * y)
{
int t, s;
if (b == 0 ){
* x = 1 ;
* y = 10 ;
return a;
}
t = extgcd(b, a % b, x, y);
s = * x;
* x = * y;
* y = s - a / b * ( * y);
return t;
}
#define max(a, b) ((a)>(b)?(a):(b))
#define min(a, b) ((a)<(b)?(a):(b))
#define swap(a, b) (a)^=(b);(b)^=(a);(a)^=(b);
int main( int argc, char ** argv)
{
long long x1, x2;
long long y1, y2;
long long x, y, t;
long long ans = 0 ;
//
scanf ( " %I64d%I64d%I64d " , & a, & b, & c);
c = - c;
scanf ( " %I64d%I64d%I64d%I64d " , & x1, & x2, & y1, & y2);
// scanf("%d%d%d", &a, &b, &c);
// scanf("%d%d", &x1, &x2);
// scanf("%I64d%d", &y1, &y2);
// c = -c;
if (a == 0 && b == 0 ){
if (c == 0 ){
ans = (x2 - x1 + 1 ) * (y2 - y1 + 1 );
}
} else if (a == 0 ){
if (c % b == 0 && c / b >= y1 && c / b <= y2){
ans = x2 - x1 + 1 ;
}
} else if (b == 0 ){
if (c % a == 0 && c / a >= x1 && c / a <= x2){
ans = y2 - y1 + 1 ;
}
} else {
t = extgcd(a, b, & x, & y);
if (c % t == 0 ){
x *= c / t;
y *= c / t;
// printf("%d %d\n", x, y);
long long lx, ly;
long long rx, ry;
lx = (x1 <= x || (x1 - x) * t % b == 0 ) ? ((x1 - x) * t / b) : ((x1 - x) * t / b + 1 );
rx = (x2 >= x || (x2 - x) * t % b == 0 ) ? ((x2 - x) * t / b) : ((x2 - x) * t / b - 1 );
ly = (y1 <= y || (y - y1) * t % a == 0 ) ? ((y - y1) * t / a) : ((y - y1) * t / a - 1 );
ry = (y2 >= y || (y - y2) * t % a == 0 ) ? ((y - y2) * t / a) : ((y - y2) * t / a + 1 );
if (lx > rx){
swap(lx, rx);
}
if (ly > ry){
swap(ly, ry);
}
// printf("%d %d %d %d\n", lx, rx, ly, ry);
if (ry >= lx && rx >= ly){
ans = min(rx, ry) - max(lx, ly) + 1 ;
}
}
}
printf( " %I64d\n " , ans);
return 0 ;
}