您的位置:首页 > 大数据 > 人工智能

【 2013 Multi-University Training Contest 7 】

2013-08-13 23:34 453 查看
HDU 4666 Hyperspace

曼哈顿距离:|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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: