您的位置:首页 > 其它

SGU 106 The equation 翻译 题解

2011-06-06 21:58 477 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: