http://acm.hdu.edu.cn/showproblem.php?pid=1348
造城墙问题,求出凸包加上一圈圆的周长即可
凸包模板题
#include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <string> #include <queue> #include <map> #include <iostream> #include <algorithm> using namespace std; #define RD(x) scanf("%d",&x) #define RD2(x,y) scanf("%d%d",&x,&y) #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define clr0(x) memset(x,0,sizeof(x)) #define eps 1e-9 const double pi = acos(-1.0); typedef long long LL; const int modo = 1e9 + 7; const int maxn = 1e4 + 5; struct point{ int x,y; }a[maxn]; int b[maxn]; bool cmp(point a,point b) { return a.x < b.x || (a.x == b.x && a.y < b.y); } double dis(point a,point b) { return sqrt(double((a.x-b.x)*(a.x-b.x)) + double((a.y - b.y)*(a.y - b.y))); } int cj(point a,point b,point c) { return (a.x - c.x) * (b.y - c.y) - (a.y - c.y) *(b.x - c.x); } int m; void graham(int n) { sort(a,a+n,cmp); b[0] = 0,b[1] = 1,b[2] = 2; int k = 1; for(int i = 2;i < n;++i){ while(k && cj(a[i],a[b[k]],a[b[k-1]]) >= 0) --k; b[++k] = i; } m = k; b[++k] = n - 2; for(int i = n - 3;i >= 0;--i){ while(k != m && cj(a[i],a[b[k]],a[b[k-1]]) >= 0) --k; b[++k] = i; } m = k; } int main() { int n,_;double f; RD(_); while(_--){ RD(n); scanf("%lf",&f); for(int i = 0;i < n;++i){ RD2(a[i].x,a[i].y); } graham(n); double ans = 0; for(int i = 0;i < m;++i) ans += dis(a[b[i]],a[b[i+1]]); ans += dis(a[b[m]],a[b[0]]); ans += pi * 2 *f; printf("%.0lf\n",ans); if(_>0) puts(""); } return 0; }