【 2013 Multi-University Training Contest 7 】

HDU 4666 Hyperspace

曼哈顿距离:|x1-x2|+|y1-y2|。

最远曼哈顿距离,枚举x1与x2的关系以及y1与y2的关系,取最大值就是答案。

 1 #include<cstdio>
 2 #include<set>
 3 #define oo 0x7FFFFFFF
 4 #define MAXM 35
 5 #define MAXN 100010
 6 using namespace std;
 7 multiset<int> myset[MAXM];
 8 struct Ask {
 9     int cmd;
10     int arr[MAXM];
11 } q[MAXN];
12 int main() {
13     int n, m;
14     int i, j, k;
15     int tmp;
16     int res;
17     int ans;
18     multiset<int>::iterator it1, it2;
19     while (~scanf("%d%d", &n, &m)) {
20         for (i = 0; i < MAXM; i++) {
21             myset[i].clear();
22         }
23         for (i = 1; i <= n; i++) {
24             scanf("%d", &q[i].cmd);
25             if (q[i].cmd == 0) {
26                 for (j = 0; j < m; j++) {
27                     scanf("%d", &q[i].arr[j]);
28                 }
29             } else {
30                 scanf("%d", &tmp);
31                 q[i].cmd = q[tmp].cmd ^ 1;
32                 for (j = 0; j < m; j++) {
33                     q[i].arr[j] = q[tmp].arr[j];
34                 }
35             }
36         }
37         for (i = 1; i <= n; i++) {
38             if (q[i].cmd == 0) {
39                 for (j = 0; j < (1 << m); j++) {
40                     tmp = j;
41                     res = 0;
42                     for (k = 0; k < m; tmp >>= 1, k++) {
43                         if (tmp & 1) {
44                             res -= q[i].arr[k];
45                         } else {
46                             res += q[i].arr[k];
47                         }
48                     }
49                     myset[j].insert(res);
50                 }
51             } else {
52                 for (j = 0; j < (1 << m); j++) {
53                     tmp = j;
54                     res = 0;
55                     for (k = 0; k < m; tmp >>= 1, k++) {
56                         if (tmp & 1) {
57                             res -= q[i].arr[k];
58                         } else {
59                             res += q[i].arr[k];
60                         }
61                     }
62                     myset[j].erase(myset[j].find(res));
63                 }
64             }
65             ans = -oo;
66             for (j = 0; j < (1 << m); j++) {
67                 if (myset[j].size() > 1) {
68                     break;
69                 }
70             }
71             if (j >= (1 << m)) {
72                 ans = 0;
73             } else {
74                 for (j = 0; j < (1 << m); j++) {
75                     if (myset[j].size() > 1) {
76                         it1 = myset[j].end();
77                         it1--;
78                         it2 = myset[j].begin();
79                         ans = max(ans, (*it1 - *it2));
80                     }
81                 }
82             }
83             printf("%d
", ans);
84         }
85     }
86     return 0;
87 }
View Code

HDU 4667 Building Fence

三角形上的点当作普通点。

点与圆的切点可能是凸包上的点。

两圆公切线与圆的交点也可能是凸包上的点。

凸包上两个点属于同一个圆,则长度等于弧长。否则长度就是线段距离。

  1 #include<cstdio>
  2 #include<cmath>
  3 #include<vector>
  4 #include<algorithm>
  5 #define MAXN 500010
  6 #define EPS 1e-8
  7 const double PI = acos(-1.0);
  8 using namespace std;
  9 struct Point {
 10     double x, y;
 11     int idx;
 12     Point(double _x = 0, double _y = 0, int _idx = 0) {
 13         x = _x;
 14         y = _y;
 15         idx = _idx;
 16     }
 17 };
 18 struct Circle {
 19     Point o;
 20     double r;
 21 };
 22 vector<Point> p;
 23 Point st[MAXN];
 24 int top;
 25 Circle c[MAXN];
 26 inline int dbcmp(double x, double y) {
 27     if (fabs(x - y) < EPS) {
 28         return 0;
 29     } else {
 30         return x > y ? 1 : -1;
 31     }
 32 }
 33 bool cmp(Point p1, Point p2) {
 34     if (dbcmp(p1.y, p2.y)) {
 35         return p1.y < p2.y;
 36     } else {
 37         return p1.x < p2.x;
 38     }
 39 }
 40 Point operator+(Point p1, Point p2) {
 41     return Point(p1.x + p2.x, p1.y + p2.y);
 42 }
 43 Point operator-(Point p1, Point p2) {
 44     return Point(p1.x - p2.x, p1.y - p2.y);
 45 }
 46 Point operator*(Point p1, double k) {
 47     return Point(p1.x * k, p1.y * k);
 48 }
 49 Point Rotate(Point p, double angle) {
 50     Point res;
 51     res.x = p.x * cos(angle) - p.y * sin(angle);
 52     res.y = p.x * sin(angle) + p.y * cos(angle);
 53     return res;
 54 }
 55 void TangentPoint_PC(Point poi, Point o, double r, Point &result1,
 56         Point &result2) {
 57     double line = sqrt(
 58             (poi.x - o.x) * (poi.x - o.x) + (poi.y - o.y) * (poi.y - o.y));
 59     double angle = acos(r / line);
 60     Point unitvector, lin;
 61     lin.x = poi.x - o.x;
 62     lin.y = poi.y - o.y;
 63     unitvector.x = lin.x / sqrt(lin.x * lin.x + lin.y * lin.y) * r;
 64     unitvector.y = lin.y / sqrt(lin.x * lin.x + lin.y * lin.y) * r;
 65     result1 = Rotate(unitvector, -angle);
 66     result2 = Rotate(unitvector, angle);
 67     result1.x += o.x;
 68     result1.y += o.y;
 69     result2.x += o.x;
 70     result2.y += o.y;
 71     return;
 72 }
 73 inline double dist(Point p1, Point p2) {
 74     return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
 75 }
 76 void TangentPoint_CC(Circle c1, Circle c2) {
 77     if (dbcmp(c1.r, c2.r) > 0) {
 78         swap(c1, c2);
 79     }
 80     double c2c = dist(c1.o, c2.o);
 81     double height = c2.r - c1.r;
 82     double alpha = asin(height / c2c) + PI / 2;
 83     Point v1, v2, tmp;
 84     v1 = c2.o - c1.o;
 85     double len = dist(v1, Point(0, 0));
 86     v1.x /= len;
 87     v1.y /= len;
 88 
 89     v2 = Rotate(v1, alpha);
 90     tmp = v2 * c1.r + c1.o;
 91     tmp.idx = c1.o.idx;
 92     p.push_back(tmp);
 93     tmp = v2 * c2.r + c2.o;
 94     tmp.idx = c2.o.idx;
 95     p.push_back(tmp);
 96 
 97     v2 = Rotate(v1, -alpha);
 98     tmp = v2 * c1.r + c1.o;
 99     tmp.idx = c1.o.idx;
100     p.push_back(tmp);
101     tmp = v2 * c2.r + c2.o;
102     tmp.idx = c2.o.idx;
103     p.push_back(tmp);
104 }
105 inline double xmult(Point p0, Point p1, Point p2) {
106     return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
107 }
108 double dot(Point a, Point b) {
109     return a.x * b.x + a.y * b.y;
110 }
111 double cross(Point a, Point b) {
112     return a.x * b.y - a.y * b.x;
113 }
114 double len(Point a) {
115     return sqrt(a.x * a.x + a.y * a.y);
116 }
117 double angle(Point a, Point b) {
118     double ret = acos(dot(a, b) / (len(a) * len(b)));
119     if (cross(a, b) > 0) {
120         return ret;
121     } else {
122         return 2 * PI - ret;
123     }
124 }
125 int main() {
126     int n, m;
127     int i, j;
128     double x, y;
129     int tmp;
130     Point p1, p2;
131     double ans;
132     while (~scanf("%d%d", &n, &m)) {
133         p.clear();
134         for (i = 0; i < n; i++) {
135             scanf("%lf%lf%lf", &x, &y, &c[i].r);
136             c[i].o = Point(x, y, i);
137         }
138         for (i = 0; i < m; i++) {
139             for (j = 0; j < 3; j++) {
140                 scanf("%lf%lf", &x, &y);
141                 p.push_back(Point(x, y, -1));
142             }
143         }
144         for (i = 0; i < n; i++) {
145             for (j = 0; j < 3 * m; j++) {
146                 TangentPoint_PC(p[j], c[i].o, c[i].r, p1, p2);
147                 p1.idx = p2.idx = c[i].o.idx;
148                 p.push_back(p1);
149                 p.push_back(p2);
150             }
151         }
152         for (i = 0; i < n; i++) {
153             for (j = i + 1; j < n; j++) {
154                 TangentPoint_CC(c[i], c[j]);
155             }
156         }
157         sort(p.begin(), p.end(), cmp);
158         top = -1;
159         for (i = 0; i < (int) p.size(); i++) {
160             while (top > 0 && dbcmp(xmult(st[top - 1], st[top], p[i]), 0) <= 0) {
161                 top--;
162             }
163             st[++top] = p[i];
164         }
165         tmp = top;
166         for (i = p.size() - 2; i >= 0; i--) {
167             while (top > tmp && dbcmp(xmult(st[top - 1], st[top], p[i]), 0) <= 0) {
168                 top--;
169             }
170             st[++top] = p[i];
171         }
172         if (n == 1 && m == 0) {
173             ans = 2 * PI * c[0].r;
174         } else {
175             ans = 0;
176             for (i = 0; i < top; i++) {
177                 if (st[i].idx < 0 || st[i + 1].idx < 0
178                         || st[i].idx != st[i + 1].idx) {
179                     ans += dist(st[i], st[i + 1]);
180                 } else {
181                     ans += c[st[i].idx].r
182                             * angle(st[i] - c[st[i].idx].o,
183                                     st[i + 1] - c[st[i].idx].o);
184                 }
185             }
186         }
187         printf("%.5lf
", ans);
188     }
189     return 0;
190 }
View Code
原文地址:https://www.cnblogs.com/DrunBee/p/3256251.html