HDU 5130 【2014广州现场赛 D】 Signal Interference
2015-11-06 00:31
239 查看
http://acm.hdu.edu.cn/showproblem.php?pid=5130
xO=k2×(1k+1+1k−1),r=k2×|1k+1−1k−1|
做坐标变换后:
x=x0+xO×dx
y=y0+xO×dy
R=dx2+dy2−−−−−−−−√
题目化为求多边形与圆的面积交
注意:输出可能需要fabs
题意
给A,B,一个多边形,问多边形里PBPA<=k的面积题解
平面上PBPA<=k组成的点的集合为阿波罗尼斯圆。特别的,若A(0,0),B(1,0),PBPA<=k:xO=k2×(1k+1+1k−1),r=k2×|1k+1−1k−1|
做坐标变换后:
x=x0+xO×dx
y=y0+xO×dy
R=dx2+dy2−−−−−−−−√
题目化为求多边形与圆的面积交
注意:输出可能需要fabs
code
// by wangyifeng #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<cmath> using namespace std; const int maxn = 11000; const double pi = acos(-1.0); double eps = 1e-10; struct point { double x, y; point() :x(0), y(0){} point (double a, double b) :x(a), y(b) {} friend point operator + (const point &a, const point &b) { return point(a.x + b.x, a.y + b.y); } friend point operator - (const point &a, const point &b) { return point(a.x - b.x, a.y - b.y); } friend point operator * (const point &a, const double &b) { return point(a.x*b, a.y * b); } friend point operator * (const double &a, const point &b) { return point(a*b.x, a*b.y); } friend point operator / (const point &a, const double &b) { return point(a.x/b, a.y / b); } void operator = (const point &b) { x = b.x; y = b.y; } }; int dcmp(double k) { return k < -eps ? -1 : k > eps ? 1 : 0; } double dot(const point &a, const point &b) { return a.x * b.x + a.y *b.y; } double cross(const point &a, const point &b) { return a.x * b.y - a.y * b.x; } double abs(const point &o) { return sqrt(dot(o, o)); } point crosspt(const point &a, const point &b, const point &p, const point &q) { double a1 = cross(b-a, p-a); double a2 = cross(b-a, q-a); return (p*a2 - q*a1) / (a2 - a1); } point res[maxn]; double r; int n; double mysqrt(double n) { return sqrt(max(0.0, n)); } double sqr(double x) { return x*x; } void circle_cross_line(point a, point b, point o, double r, point ret[], int& num) { double x0 = o.x, y0 = o.y; double x1 = a.x, y1 = a.y; double x2 = b.x, y2 = b.y; double dx = x2 - x1, dy = y2 - y1; double A = dx * dx + dy * dy; double B = 2 * dx * (x1 - x0) + 2 *dy * (y1 - y0); double C = sqr(x1-x0) + sqr(y1 - y0) - sqr(r); double delta = B*B - 4*A*C; num = 0; if (dcmp(delta) >= 0) { double t1 = (-B - mysqrt(delta)) / (2*A); double t2 = (-B + mysqrt(delta)) / (2*A); if (dcmp(t1 - 1) <= 0 && dcmp(t1) >= 0) { ret[num++] = point(x1 + t1*dx, y1 + t1*dy); } if (dcmp(t2-1) <= 0 && dcmp(t2) >= 0) { ret[num++] = point(x1+t2*dx, y1+t2*dy); } } } double sector_area(const point &a, const point &b) { double theta = atan2(a.y, a.x) - atan2(b.y, b.x); while (theta <= 0) theta += 2 * pi; while (theta > 2*pi) theta -= 2*pi; theta = min(theta, 2*pi-theta); return r*r*theta/2; } double calc(const point&a, const point &b) { point p[2]; int num = 0; int ina = dcmp(abs(a)-r) < 0; int inb = dcmp(abs(b)-r) <0; if (ina) { if (inb) { return fabs(cross(a, b)) / 2.0; } else { circle_cross_line(a, b, point(0, 0), r, p, num); return sector_area(b, p[0]) + fabs(cross(a, p[0])) / 2.0; } } else { if (inb) { circle_cross_line(a, b, point(0,0), r, p, num); return sector_area(p[0], a) + fabs(cross(p[0], b)) / 2.0; } else { circle_cross_line(a, b, point(0,0), r, p, num); if (num == 2) { return sector_area(a, p[0]) + sector_area(p[1], b) + fabs(cross(p[0], p[1]))/ 2.0; } else { return sector_area(a, b); } } } } double area() { double ret = 0; for (int i = 0; i < n; i++) { int sgn = dcmp(cross(res[i], res[i+1])); if (sgn != 0) { ret += sgn * calc(res[i], res[i+1]); } } return ret; } int main() { //freopen("d.in","r",stdin); // int n; double k; int cas = 0; while (scanf("%d%lf", &n, &k) == 2) { k = 1.0 / k; for (int i = 0; i < n; i++) { int x, y; scanf("%d%d", &x, &y); res[i].x = x; res[i].y = y; } double x1, y1, x2, y2; scanf("%lf%lf", &x1, &y1); scanf("%lf%lf", &x2, &y2); double _X = k/2.0 * (1.0 / (k-1) + 1.0 / (k+1)); double _r = k / 2.0 * fabs((1.0 / (k-1) - 1.0 / (k+1))); double px = _X * (x2 - x1) + x1; double py = _X * (y2 - y1) + y1; //printf("%lf %lf\n", px, py); r = _r * sqrt(sqr(x2-x1) + sqr(y2-y1)); // printf("%lf\n", r); // printf("%lf %lf\n", px-r, px+r); // px = 0; // py = 0; // r = 1; for (int i = 0; i < n; i++) { res[i].x -= px; res[i].y -= py; } res = res[0]; /* for (int i = 0; i <= n; i++) { printf("%lf %lf\n", res[i].x, res[i].y); }*/ printf("Case %d: %.7lf\n",++cas, fabs(area())); } return 0; }
相关文章推荐
- 简单的四则运算
- 数的奇偶性
- ACM网址
- 1272 小希的迷宫
- 1272 小希的迷宫
- hdu 1250 大数相加并用数组储存
- 矩阵的乘法操作
- 蚂蚁爬行问题
- 蚂蚁爬行问题
- 求两个数的最大公约数【ACM基础题】
- 打印出二进制中所有1的位置
- 杭电题目---一只小蜜蜂
- HDOJ 1002 A + B Problem II (Big Numbers Addition)
- 初学ACM - 半数集(Half Set)问题 NOJ 1010 / FOJ 1207
- 初学算法 - 求凸包的Garham's Scan算法的C++实现
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1002
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006