凸包計算_POJ1113
阿新 • • 發佈:2018-11-26
寫在前面
題目中除了要計算凸包之外,還要求修理的城牆要和宮殿之間的距離不小於L,那麼也就是相對於宮殿長度之外,多了一個一L為半徑的圓的距離,所以題目就得以解決
程式
#include <iostream> #include <algorithm> #include <cstdio> #include <cmath> using namespace std; typedef long long ll; const int N = 1500; const double PI = acos(-1.0); struct Point{ int x,y; }a[N],p[N]; int n,tot,l; double dis(const Point &p1,const Point &p2) { return (double)(p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y); } int multi(const Point &p0,const Point &p1, const Point &p2) { return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y); } bool cmp(const Point &p1,const Point &p2) { int x = multi(a[0],p1,p2); if(x > 0 || (x == 0 && dis(a[0],p1) < dis(a[0],p2))) return 1; return 0; } void Graham() { int k = 0; for(int i = 1;i < n;i ++) if(a[i].y < a[k].y || (a[i].y == a[k].y && a[i].x < a[k].x)) k = i; if(k != 0) swap(a[0],a[k]); sort(a+1, a+n, cmp); tot = 1, p[0] = a[0], p[1] = a[1]; for(int i = 2;i < n;i ++) { while(tot && multi(p[tot-1],p[tot],a[i]) <= 0) tot--; p[++tot] = a[i]; } } int main() { scanf("%d%d",&n,&l); for(int i = 0;i < n;i ++) scanf("%d%d",&a[i].x,&a[i].y); Graham(); double Len = sqrt(dis(p[0],p[tot])); for(int i = 0;i < tot;i ++) Len += sqrt(dis(p[i],p[i + 1])); Len += 2 * PI * l; printf("%d\n",(int)(Len+0.5)); }