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\n", ans); 84 } 85 } 86 return 0; 87 }
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\n", ans); 188 } 189 return 0; 190 }