zoj 1453 Surround the Trees

计算几何中的凸包问题
参考计算几何凸包问题介绍

算法导论上也有两种方法可以参考

/* ***********************************************
Author        :xryz
Email         :523689985@qq.com
Created Time  :3-31 22:21:41
File Name     :\Users\xryz\Desktop\SurroundtheTrees.cpp
************************************************ */

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;

int top,s[10024];//s用来当作边界点的栈
struct data
{
    double x,y;
}p[10024],temp;

double corss(data a,data b,data c)//计算叉积向量ab和向量ac
{
    return ((b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y));
}

double dis(data a,data b)//计算距离
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

//除第一个点外按极角大小排列,小的在前面,不会用sort来写……
int cmp(const void *a,const void  *b)
{
    double m;
    data *p1,*p2;
    p1=(data *)a;
    p2=(data *)b;
    m=corss(p[0],*p1,*p2);
    if(m<0) return 1;
    else if(m==0&&(dis(p[0],*p1)<dis(p[0],*p2)))
        return 1;
    else return -1;
}

int main()
{
    int n,i,j,u;
    double sum;
    while(~scanf("%d",&n)&&n)
    {
        sum=0;
        for(i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);

        if(n==1) {printf("0.00\n");continue;}
        else if(n==2) {printf("%.2f\n",2*dis(p[0],p[1]));continue;}//hdu 1392 不需要乘两倍 zoj1453需要这样写
        u=0;
        //找出最左边的点,即y坐标最小,y相同时x最小
        for(i=0;i<n;i++)
        {
            if(p[i].y<p[u].y||((p[i].y==p[u].y)&&p[i].x<p[u].x))
                u=i;
        }
        temp=p[u];p[u]=p[0];p[0]=temp;
        qsort(&p[1],n-1,sizeof(double)*2,cmp);
        for(i=0;i<=2;i++) s[i]=i;//将前面三点入栈
        top=2;
        for(i=3;i<n;i++)
        {
            while(corss(p[s[top-1]],p[s[top]],p[i])<=0) top--;//右旋顺时针,将top的点出栈
            s[++top]=i;
        }
        for(i=1;i<=top;i++)
        {
            sum+=dis(p[s[i]],p[s[i-1]]);
        }
        sum+=dis(p[s[0]],p[s[top]]);
        printf("%.2f\n",sum);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。http://xiang578.top/

posted @ 2015-04-04 16:52  xryz  阅读(145)  评论(0编辑  收藏  举报