当前位置: 代码迷 >> 综合 >> poj-1113-Wall
  详细解决方案

poj-1113-Wall

热度:35   发布时间:2023-12-19 11:23:43.0

求凸包的问题。

做法:

先求出所有点构成的凸包的周长。

再加上半径为l的圆的周长~

#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
using namespace std;
const double PI = 3.14159265358979;
struct point
{double x,y;double thera;
}a[1005],chs[1005];bool cmp1(point a,point b)
{if( a.y == b.y ) return a.x < b.x;return a.y < b.y;
}
bool cmp2(point a,point b)
{if( a.thera == b.thera )return a.x < b.x;elsereturn a.thera < b.thera;
}
double get_thera(point a0,point a1)
{return atan2((a1.y-a0.y),(a1.x-a0.x));
}
double dist_2point(point a1,point a2)
{return sqrt((a1.x-a2.x)*(a1.x-a2.x)+(a1.y-a2.y)*(a1.y-a2.y));
}bool line_3point(point a1,point a2,point a3)
{double P,Q,M;P=(a2.x - a1.x) * (a3.y - a1.y);Q=(a3.x - a1.x) * (a2.y - a1.y);M=P-Q;if(M>0)  return false;if(M<0)  return true;if(M==0) return true;return false;
}int main()
{int i,n,top;double r,len,shan,sum;while(scanf("%d%lf",&n,&r)!=EOF){len=0;for(i=0;i<n;i++)scanf("%lf%lf",&a[i].x,&a[i].y);sort(a,a+n,cmp1);for(i=0;i<n;i++)a[i].thera=get_thera(a[0],a[i]);sort(a+1,a+n,cmp2);chs[0]=a[0]; chs[1]=a[1]; chs[2]=a[2];top=2;for(i=3;i<n;i++){while(top>=1 && line_3point(chs[top-1],chs[top],a[i])){top--;}chs[++top]=a[i];}top++;for(i=0;i<top;i++)len+=dist_2point(chs[i%top],chs[(i+1)%top]);shan=2.0*PI*r;sum=shan+len;printf("%.0lf\n",sum);}return 0;
}