您的位置:首页 > Web前端

HDU 5130 【2014广州现场赛 D】 Signal Interference

2015-11-06 00:31 239 查看
http://acm.hdu.edu.cn/showproblem.php?pid=5130

题意

给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 计算几何 HDU-5130