【 2013 Multi-University Training Contest 7 】
2013-08-13 23:34
453 查看
HDU 4666 Hyperspace
曼哈顿距离:|x1-x2|+|y1-y2|。
最远曼哈顿距离,枚举x1与x2的关系以及y1与y2的关系,取最大值就是答案。
View Code
曼哈顿距离:|x1-x2|+|y1-y2|。
最远曼哈顿距离,枚举x1与x2的关系以及y1与y2的关系,取最大值就是答案。
#include<cstdio> #include<cmath> #include<vector> #include<algorithm> #define MAXN 500010 #define EPS 1e-8 const double PI = acos(-1.0); using namespace std; struct Point { double x, y; int idx; Point(double _x = 0, double _y = 0, int _idx = 0) { x = _x; y = _y; idx = _idx; } }; struct Circle { Point o; double r; }; vector<Point> p; Point st[MAXN]; int top; Circle c[MAXN]; inline int dbcmp(double x, double y) { if (fabs(x - y) < EPS) { return 0; } else { return x > y ? 1 : -1; } } bool cmp(Point p1, Point p2) { if (dbcmp(p1.y, p2.y)) { return p1.y < p2.y; } else { return p1.x < p2.x; } } Point operator+(Point p1, Point p2) { return Point(p1.x + p2.x, p1.y + p2.y); } Point operator-(Point p1, Point p2) { return Point(p1.x - p2.x, p1.y - p2.y); } Point operator*(Point p1, double k) { return Point(p1.x * k, p1.y * k); } Point Rotate(Point p, double angle) { Point res; res.x = p.x * cos(angle) - p.y * sin(angle); res.y = p.x * sin(angle) + p.y * cos(angle); return res; } void TangentPoint_PC(Point poi, Point o, double r, Point &result1, Point &result2) { double line = sqrt( (poi.x - o.x) * (poi.x - o.x) + (poi.y - o.y) * (poi.y - o.y)); double angle = acos(r / line); Point unitvector, lin; lin.x = poi.x - o.x; lin.y = poi.y - o.y; unitvector.x = lin.x / sqrt(lin.x * lin.x + lin.y * lin.y) * r; unitvector.y = lin.y / sqrt(lin.x * lin.x + lin.y * lin.y) * r; result1 = Rotate(unitvector, -angle); result2 = Rotate(unitvector, angle); result1.x += o.x; result1.y += o.y; result2.x += o.x; result2.y += o.y; return; } inline double dist(Point p1, Point p2) { return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)); } void TangentPoint_CC(Circle c1, Circle c2) { if (dbcmp(c1.r, c2.r) > 0) { swap(c1, c2); } double c2c = dist(c1.o, c2.o); double height = c2.r - c1.r; double alpha = asin(height / c2c) + PI / 2; Point v1, v2, tmp; v1 = c2.o - c1.o; double len = dist(v1, Point(0, 0)); v1.x /= len; v1.y /= len; v2 = Rotate(v1, alpha); tmp = v2 * c1.r + c1.o; tmp.idx = c1.o.idx; p.push_back(tmp); tmp = v2 * c2.r + c2.o; tmp.idx = c2.o.idx; p.push_back(tmp); v2 = Rotate(v1, -alpha); tmp = v2 * c1.r + c1.o; tmp.idx = c1.o.idx; p.push_back(tmp); tmp = v2 * c2.r + c2.o; tmp.idx = c2.o.idx; p.push_back(tmp); } inline double xmult(Point p0, Point p1, Point p2) { return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y); } double dot(Point a, Point b) { return a.x * b.x + a.y * b.y; } double cross(Point a, Point b) { return a.x * b.y - a.y * b.x; } double len(Point a) { return sqrt(a.x * a.x + a.y * a.y); } double angle(Point a, Point b) { double ret = acos(dot(a, b) / (len(a) * len(b))); if (cross(a, b) > 0) { return ret; } else { return 2 * PI - ret; } } int main() { int n, m; int i, j; double x, y; int tmp; Point p1, p2; double ans; while (~scanf("%d%d", &n, &m)) { p.clear(); for (i = 0; i < n; i++) { scanf("%lf%lf%lf", &x, &y, &c[i].r); c[i].o = Point(x, y, i); } for (i = 0; i < m; i++) { for (j = 0; j < 3; j++) { scanf("%lf%lf", &x, &y); p.push_back(Point(x, y, -1)); } } for (i = 0; i < n; i++) { for (j = 0; j < 3 * m; j++) { TangentPoint_PC(p[j], c[i].o, c[i].r, p1, p2); p1.idx = p2.idx = c[i].o.idx; p.push_back(p1); p.push_back(p2); } } for (i = 0; i < n; i++) { for (j = i + 1; j < n; j++) { TangentPoint_CC(c[i], c[j]); } } sort(p.begin(), p.end(), cmp); top = -1; for (i = 0; i < (int) p.size(); i++) { while (top > 0 && dbcmp(xmult(st[top - 1], st[top], p[i]), 0) <= 0) { top--; } st[++top] = p[i]; } tmp = top; for (i = p.size() - 2; i >= 0; i--) { while (top > tmp && dbcmp(xmult(st[top - 1], st[top], p[i]), 0) <= 0) { top--; } st[++top] = p[i]; } if (n == 1 && m == 0) { ans = 2 * PI * c[0].r; } else { ans = 0; for (i = 0; i < top; i++) { if (st[i].idx < 0 || st[i + 1].idx < 0 || st[i].idx != st[i + 1].idx) { ans += dist(st[i], st[i + 1]); } else { ans += c[st[i].idx].r * angle(st[i] - c[st[i].idx].o, st[i + 1] - c[st[i].idx].o); } } } printf("%.5lf\n", ans); } return 0; }
View Code
相关文章推荐
- Integer Partition(hdu4658)2013 Multi-University Training Contest 6 整数拆分二
- 2013 Multi-University Training Contest 5
- 2013 Multi-University Training Contest 6
- Hdu 4681 2013 Multi-University Training Contest 8 String
- 2013 Multi-University Training Contest 3 (g) The Unsolvable Problem
- hdu 4638 Group(2013 Multi-University Training Contest 4)
- 2013 Multi-University Training Contest 3
- 2013 Multi-University Training Contest 4
- 2013 Multi-University Training Contest 5 k-th point
- 2013 Multi-University Training Contest 5 解题报告(更新中)
- 2013 Multi-University Training Contest 8
- 2013 Multi-University Training Contest 3 (g) The Unsolvable Problem
- 2013 Multi-University Training Contest 4
- 2013 Multi-University Training Contest 2
- 2013 Multi-University Training Contest 3
- 2013 Multi-University Training Contest 6
- 2013 Multi-University Training Contest 1
- 2013 Multi-University Training Contest 1
- 2013 Multi-University Training Contest 1