POJ 1113 wall

POJ上题目原文

    题目大意就是给你一些点,然后你找出将他们包围所需要的最少的代价,相当于就是求用一根绳子将他们包围起来,求绳子的长度。有个特殊的要求就是,必须绳子与最外面的构成的多边形的距离必须大于等于 L 。其实就是将多边形的周长加上以 L 为半径的圆的周长即可。

    裸的凸包,要是对求凸包的代码熟悉的话,直接上模板,由于本人刚写凸包没多久,所以还是自己老老实实的写了一遍凸包,当做是复习吧,不过对凸包的理解又加深了点。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define INF 1000000
#define N 10005
using namespace std;
struct point
{
    int x,y;
    double len,theta;
} g[N];
void qqsort(int st,int en)
{
    int i=st,j=en;
    g[0]=g[i];
    while(i<j)
    {
        while(i<j && g[0].theta>=g[j].theta) j--;
        if(i<j) { g[i]=g[j]; i++; }
        while(i<j && g[0].theta<=g[i].theta) i++;
        if(i<j) { g[j]=g[i]; j--; }
    }
    g[i]=g[0];
    if(st<i-1) qqsort(st,i-1);
    if(i+1<en) qqsort(i+1,en);
}
void graham(int *n)
{
    int k=1;
    for(int i=2;i<=*n;i++)
      if((g[i].y<g[k].y)||(g[i].y==g[k].y && g[i].x<g[k].x)) k=i;
    g[0]=g[k]; g[k]=g[1]; g[1]=g[0];
    for(int i=2;i<=*n;i++)
    {
        g[i].len=sqrt((g[i].x-g[1].x)*(g[i].x-g[1].x)+(g[i].y-g[1].y)*(g[i].y-g[1].y));
        g[i].theta=(g[i].x-g[1].x)/g[i].len;
    }
    qqsort(2,*n);
    point map[N]; int tot=0;
    int p=1;
    while(p<=*n)
    {
        int k=p;
        while(g[p].theta==g[p+1].theta)
        {
            if(g[k].len<g[p+1].len) k=p+1;
            p++;
        }
        map[++tot]=g[k];
        p++;
    }
    *n=tot; tot=3;
    g[1]=map[1]; g[2]=map[2]; g[3]=map[3];
    for(int i=4;i<=*n;i++)
    {
        double chaji=(g[tot].x-g[tot-1].x)*(map[i].y-g[tot].y)-(map[i].x-g[tot].x)*(g[tot].y-g[tot-1].y);
        while(chaji<=0)
        {
            tot--;
            chaji=(g[tot].x-g[tot-1].x)*(map[i].y-g[tot].y)-(map[i].x-g[tot].x)*(g[tot].y-g[tot-1].y);
        }
        g[++tot]=map[i];
    }
    *n=tot;
}
double dis(int x1,int y1,int x2,int y2)
{
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int main()
{
    int n,l;
    scanf("%d%d",&n,&l);
    for(int i=1;i<=n;i++) scanf("%d%d",&g[i].x,&g[i].y);
    graham(&n);
    //for(int i=1;i<=n;i++) printf("(%3d,%3d)\n",g[i].x,g[i].y);
    double ans=3.1415926*l*2;
    g[0]=g[n];
    for(int i=1;i<=n;i++) ans+=dis(g[i-1].x,g[i-1].y,g[i].x,g[i].y);
    printf("%d\n",(int)(0.5+ans));
    return 0;
}


你可能感兴趣的:(POJ 1113 wall)