POJ 1113

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Masqueradey/article/details/52702977

这道题是给定点集,求出凸包,然后在外面构筑一个城墙,使凸包每一点到围墙距离小于一个给定的值L。最终可以等价于凸包周长之和再加上以L为半径的圆的周长。

代码:

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdlib>
using namespace std;
#define maxn 2000
const double PI=3.1415926;
struct point{
    int x,y;
}points[maxn],s[maxn];
int top,N,L;
double dis(point a,point b){
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int multiply(point a,point b,point c){
       return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
bool cmp(point a , point b){
       int m;
       m = multiply(points[1],a,b) ;
       if(m>0)return 1;
       else if(m==0&&(dis(points[1],a)<dis(points[1],b)))return 1;
       return 0;
}
void tubao(){
       int i,j;
       s[1].x=points[1].x;
       s[1].y=points[1].y;
       s[2].x=points[2].x;
       s[2].y=points[2].y;
       top=2;
       for(i=3;i<=N;i++)
       {
        for(;top>=2;)
        {
         if(multiply(s[top-1],s[top],points[i])<=0){top--;continue;}
         break;
        }
        s[++top]=points[i];
       }
       return;
}
int main(){
    ios::sync_with_stdio(false);
    int i,j,pos=1;
    double sum=0;
    cin>>N>>L;
    for(i=1;i<=N;i++)cin>>points[i].x>>points[i].y;
    for(i=2;i<=N;i++)
    {
     if(points[i].x<points[pos].x){pos=i;continue;}
     else if(points[i].x==points[pos].x&&points[i].y<points[pos].y){pos=i;continue;}
    }
    swap(points[1],points[pos]);
    sort(points+2,points+N+1,cmp);
    tubao();
     for(i=1;i<top;i++)sum+=dis(s[i],s[i+1]);
     sum+=dis(s[1],s[top]);
     sum+=2*PI*L;
     cout<<(int)(sum+0.5)<<endl;
    system("pause");
    return 0;

}






猜你喜欢

转载自blog.csdn.net/Masqueradey/article/details/52702977