Poj 1113 Wall (凸包Graham水平序)
阿新 • • 發佈:2019-02-17
以前做過的題,現在重新寫下。
以前的解題報告:http://blog.csdn.net/whyorwhnt/article/details/8316442
#include <cmath> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const double PI=acos(-1.0); const double eps=1e-8; const int N=1005; struct Point //點,向量 { double x,y; Point(){} Point(double _x,double _y) {x=_x;y=_y;} void Get () {scanf("%lf%lf",&x,&y);} Point operator-(const Point &b)const {return Point(x-b.x,y-b.y);} Point operator+(const Point &b) {return Point(x+b.x,y+b.y);} Point operator*(const double k) //數乘 {return Point(x*k,y*k);} double operator*(const Point a) //點乘 {return x*a.x+y*a.y;} double operator^(const Point a) //叉乘 {return x*a.y-y*a.x;} int DB (double dx) //判0函式 { if(fabs(dx)<eps) return 0; return dx>0?1:-1; } //呼叫點a的該函式 //返回1點a在向量bc的左側 //返回-1點a在向量bc的右側 //返回0點a在向量bc這條直線上 int Cross (Point b,Point c) {return DB((b.x-x)*(c.y-y)-(c.x-x)*(b.y-y));} bool operator < (const Point &b)const //用於排序 { if (fabs(y-b.y)<eps) return x-b.x<0; return y-b.y<0; } double Dis (Point ch) {return sqrt((x-ch.x)*(x-ch.x)+(y-ch.y)*(y-ch.y));} }pt[N],ch[N]; int n,len; //求凸包函式 //pt:所有的點,n個,pt[0]到pt[n-1] //ch:求完的凸包中的點,len個,q[0]到q[len-1] void Graham (Point pt[],Point ch[],int &len,int n) //只儲存凸包頂點 { int i,top=1; sort(pt,pt+n); ch[0]=pt[0]; ch[1]=pt[1]; for (i=2;i<n;i++) { while (top>0 && ch[top-1].Cross(ch[top],pt[i]) <= 0) top--; ch[++top]=pt[i]; } int temp=top; for (i=n-2;i>=0;i--) { while (top>temp && ch[top-1].Cross(ch[top],pt[i]) <= 0) top--; ch[++top]=pt[i]; } len=top; } int main () { int L,i,n,len; double ans=0; scanf("%d%d",&n,&L); for (i=0;i<n;i++) pt[i].Get(); Graham (pt,ch,len,n); for (i=0;i<len;i++) ans+=ch[i].Dis(ch[(i+1)%len]); ans+=PI*2*L; printf("%.0lf\n",ans); return 0; }