求ax + by + c = 0在[x1, x2], [y1, y2]区间内有多少组解?
2017-08-05 10:36
337 查看
题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=106
题意:求ax
+ by + c = 0在[x1, x2], [y1, y2]区间内有多少组解?
解析:
①令c
= -c有ax + by = c,可用扩展欧几里德解方程解出特解
当然要先考虑a
= 0, b = 0, c = 0的情况进行特判
例如:a
= 0, b = 1, c = 3,x∈[x1,
x2], y∈[3, 4]
即可得知有方程有x2-x1+1个解,因为x可以区间内任意,且y=3这个解在区间内,其他情况同理了
②然后就是关键了,用的是扩展欧几里德通解式:(设一整数k,x0为x的特解)
1、x1
<= x0+k*b <= x2
2、y0
= (c - a*x0) / b
3、y1
<= y0+k'*b <= y2
解出k和k'的范围[s,
e]!
注意了,例如解x1
<= x0+k*b:
当b<0时两边同时除以b,<=要变成>=号
--->k
<= (x1-x0) / b
然后最关键就是除不尽应该向什么方向舍入?
区间[s,
e]的舍入方向:
正数s,
e的情况:
可见s
= (x1-x0)/b还要+1,e直接除即可
负数s, e的情况:
可见e
= (x1-x0)/b还要-1,s直接除即可
③最后得到x的k的范围[s1,
e1], y的k'的范围[s2, e2]
因为x增加必然导致y减小,所以有:
举个例子,如图所示:令-e2作为s2,令-s2作为e2,答案为[-e2,
e1]
所以答案ans
= min (e1, e2') - max (s1, s2') + 1;
人一我百!人十我万!永不放弃~~~怀着自信的心,去追逐梦想
题意:求ax
+ by + c = 0在[x1, x2], [y1, y2]区间内有多少组解?
解析:
①令c
= -c有ax + by = c,可用扩展欧几里德解方程解出特解
当然要先考虑a
= 0, b = 0, c = 0的情况进行特判
例如:a
= 0, b = 1, c = 3,x∈[x1,
x2], y∈[3, 4]
即可得知有方程有x2-x1+1个解,因为x可以区间内任意,且y=3这个解在区间内,其他情况同理了
②然后就是关键了,用的是扩展欧几里德通解式:(设一整数k,x0为x的特解)
1、x1
<= x0+k*b <= x2
2、y0
= (c - a*x0) / b
3、y1
<= y0+k'*b <= y2
解出k和k'的范围[s,
e]!
注意了,例如解x1
<= x0+k*b:
当b<0时两边同时除以b,<=要变成>=号
--->k
<= (x1-x0) / b
然后最关键就是除不尽应该向什么方向舍入?
区间[s,
e]的舍入方向:
正数s,
e的情况:
可见s
= (x1-x0)/b还要+1,e直接除即可
负数s, e的情况:
可见e
= (x1-x0)/b还要-1,s直接除即可
③最后得到x的k的范围[s1,
e1], y的k'的范围[s2, e2]
因为x增加必然导致y减小,所以有:
举个例子,如图所示:令-e2作为s2,令-s2作为e2,答案为[-e2,
e1]
所以答案ans
= min (e1, e2') - max (s1, s2') + 1;
#include <iostream> #include <stdio.h> #include <string> #include <cstring> #include <stdlib.h> #include <map> #include <algorithm> #include <math.h> using namespace std; #define M 1005 #define LL long long LL gcd (LL a, LL b) { return b ? gcd (b, a%b) : a; } void Egcd (LL a, LL b, LL &x, LL &y) { if (b == 0) { x = 1, y = 0; return ; } LL tp; Egcd (b, a%b, x, y); tp = x; x = y; y = tp - a/b*y; } LL cal (LL f, LL n, int key) //处理舍入问题 { if (f % n == 0) return f/n; if (key == 0) { if (f * n < 0) return f/n; return f/n+1; } if (f * n < 0) return f/n-1; return f/n; } LL a, b, c; LL solve (LL &x1, LL &x2, LL &y1, LL &y2) { LL d, x, y, s1, e1, s2, e2; c = -c; /***********************特判***********************/ if (a == 0 && b == 0 && c == 0) return (x2-x1+1) * (y2-y1+1); if (a == 0 && b == 0) return 0; if (a == 0) { if (c % b != 0) return 0; y = c / b; if (y >= y1 && y <= y2) return x2 - x1 + 1; return 0; } if (b == 0) { if (c % a != 0) return 0; x = c / a; if (x >= x1 && x <= x2) return y2 - y1 + 1; return 0; } /***********************特判***********************/ d = gcd (a, b); if (c % d != 0) return 0; a /= d, b /= d, c /= d; Egcd (a, b, x, y); x *= c; x = (x % b + b) % b; //x的特解 s1 = cal (x1-x, b, b<0); //s1 e1 = cal (x2-x, b, b>0); //e1 y = (c - a*x) / b; //有了x,求对应的y e2 = -cal (y1-y, a, a<0); //e2' = -s2 s2 = -cal (y2-y, a, a>0); //s2' = -e2 if (b < 0) s1 ^= e1, e1 ^= s1, s1 ^= e1; //b为负数,变号导致区间头尾互换 if (a < 0) s2 ^= e2, e2 ^= s2, s2 ^= e2; //同理 LL ans = min (e1, e2) - max (s1, s2) + 1; if (ans < 0) ans = 0; return ans; } int main() { LL x1, x2, y1, y2; while (~scanf ("%lld%lld%lld", &a, &b, &c)) { scanf ("%lld%lld%lld%lld", &x1, &x2, &y1, &y2); printf ("%lld\n", solve (x1, x2, y1, y2)); } return 0; }
人一我百!人十我万!永不放弃~~~怀着自信的心,去追逐梦想
相关文章推荐
- ax+by=c 且X∈[x1,x2] Y∈[y1,y2] 可行解组数 exgcd
- 根据三个点(x1,y1)、(x2,y2)、(x3,y3),确定方程y=aX^2 + bX + c,带入X求得Y
- Hdu 4052 Adding New Machine(给你W*H大小的矩形,其中有N个地区不能使用(给出了这个地区的两个顶点的坐标即(x1,y1)和(x2,y2)),问能下多少个1*M的矩形)
- 二货小易有一个W*H的网格盒子,网格的行编号为0~H-1,网格的列编号为0~W-1。每个格子至多可以放一块蛋糕,任意两块蛋糕的欧几里得距离不能等于2。 对于两个格子坐标(x1,y1),(x2,y2)的欧几里得距离为: ( (x1-x2) * (x1-x2) + (y1-y2) * (y1-y2) ) 的算术平方根 小易想知道最多可以放多少块蛋糕在网格盒子里。 输入描述: 每组数组包含网格长宽W,
- sgu 106. The equation 已知ax + by + c = 0 ,求解在[x1,x2],[y1,y2]区间的解的个数
- 点(x3,y3)到经过点(x1,y1)和点(x2,y2)的直线的最短距离
- 距离(x1,y1)到(x2,y2)的距离
- 360oj 输入两点坐标(X1,Y1),(X2,Y2),计算并输出两点间的距离。
- 两点距离 时间限制:3000 ms | 内存限制:65535 KB 难度:1 描述 输入两点坐标(X1,Y1),(X2,Y2)(0<=x1,x2,y1,y2<=1000),计算并输出两点间的距离。
- hdu5794 A Simple Chess 容斥+Lucas 从(1,1)开始出发,每一步从(x1,y1)到达(x2,y2)满足(x2−x1)^2+(y2−y1)^2=5, x2>x1,y2>y1; 其实就是走日字。而且是往(n,m)方向走的日字。还有r个障碍物,障碍物不可以到达。求(1,1)到(n,m)的路径条数。
- 判断点是否在A(x1,y1),B(x2,y2)连线的直线上
- C/C++—— 输入两点坐标(X1,Y1),(X2,Y2),计算并输出两点间的距离
- 我用JAVA里的drawline(x1,y1,x2,y2)和repaint()方法画出的直线不是一条直线
- VB6.0自制Line控件时实现X1,Y1,X2,Y2属性
- 已知直线上的两点 A(x1, y1), B(x2, y2) 和另外一点 C(x0, y0),求C点到直线的距离。
- 输入两个坐标(x1,y1),(x2,y2),计算并输出两点间的距离
- 编程题-----三个顶点的坐标(x1,y1),(x2,y2),(x3,y3)什么方法求三角形的面积最简单
- 输入两个坐标(x1,y1),(x2,y2),计算并输出两点间的距离
- 两条线段知道端点line1(x1,y1)(x2,y2)line2(x3,y3)(x4,y4),判断两条线段是否相交,交点坐标(x,y)
- 二货小易有一个W*H的网格盒子,网格的行编号为0~H-1,网格的列编号为0~W-1。每个格子至多可以放一块蛋糕,任意两块蛋糕的欧几里得距离不能等于2。 对于两个格子坐标(x1,y1),(x2,y2)的