SGU 106.The equation
时间限制:0.25s
内存限制: 4Mib
题目
有一个方程ax + by + c = 0。 给定a,b,c,x1,x2,y1,y2,你需要得出,有多少整根满足以下条件: x1<=x<=x2, y1<=y<=y2。
输入
输入包含整数 a,b,c,x1,x2,y1,y2 用空格或者空行隔开。所有数的绝对值不超过10^8。
输出
输出答案
输入样例
1 1 -3
0 4
0 4
输出样例
4
{=======================================}
分析:
题中要求解一个二元一次不定方程,使用拓展欧几里得定理.
另外还要求一个区间内的解
当求出一个特解(x,y)后
xn =x+k1(b/gcd(a,b);k1为整数
yn =y+k2(a/gcd(a,b));k2为整数
将给出范围代入,得到k1 和k2 的范围,再取交集,就可以得到答案了。
而且对于a,b中有0存在的情况需要特判。
参考代码
#include <iostream>
using namespace std;
typedef __int64 I64;
I64 a, b, c, x1, x2, y1, y2, x, y, ans = 0;
I64 mL[2], mR[2], t = -1;
I64 Exgcd (I64 a, I64 b, I64 &x, I64 &y) {
if (b == 0) {
x = 1, y = 0;
return a;
}
I64 temp = Exgcd (b, a % b, x, y);
I64 t = x;
x = y;
y = t - a / b * y;
return temp;
}
void update (I64 L, I64 R, I64 wa) {
if (wa < 0) {
L = -L, R = -R, wa = -wa;
swap (L, R);
}
mL[++t] = (L <= 0) ? L / wa : (L - 1) / wa + 1 ;
mR[t] = (R >= 0) ? R / wa : (R + 1) / wa - 1 ;
}
int main() {
cin >> a >> b >> c >> x1 >> x2 >> 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 {
I64 d = Exgcd (a, b, x, y);
if (c % d == 0) {
I64 p = c / d;
update (x1 - p * x, x2 - p * x, b / d);
update (y1 - p * y, y2 - p * y, -a / d);
ans = min (mR[0], mR[1]) - max (mL[0], mL[1]) + 1;
if (ans < 0) ans = 0;
}
}
cout << ans << endl;
}
http://www.cnblogs.com/keam37/ keam所有 转载请注明出处

浙公网安备 33010602011771号