• zoj 1453 Surround the Trees


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

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

    /* ***********************************************
    Author        :xryz
    Email         :523689985@qq.com
    Created Time  :3-31 22:21:41
    File Name     :UsersxryzDesktopSurroundtheTrees.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
    ");continue;}
            else if(n==2) {printf("%.2f
    ",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
    ",sum);
        }
        return 0;
    }
    

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

  • 相关阅读:
    ClickHouse 监控及备份 (三)ClickHouse 配置
    ClickHouse 监控及备份 (二)Prometheus&Grafana 的安装
    ClickHouse 监控及备份 (一)ClickHouse 监控概述
    ClickHouse 高级(八)运维(1)常见问题排查
    ClickHouse 高级(七)MaterializeMySQL 引擎
    ClickHouse 高级(六)物化视图
    使用Iperf调整网络
    WinForm中DataGridView的使用(四)
    数据库设计经验总结
    WinForm使用Label控件模拟分割线(竖向)
  • 原文地址:https://www.cnblogs.com/xryz/p/4848050.html
Copyright © 2020-2023  润新知