zoukankan      html  css  js  c++  java
  • HDU 1392 凸包模板题,求凸包周长

    1、HDU 1392 Surround the Trees  

    2、题意:就是求凸包周长

    3、总结:第一次做计算几何,没办法,还是看了大牛的博客

    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    #include<cstdio>
    #include<cstdlib>
    #define F(i,a,b) for (int i=a;i<b;i++)
    #define FF(i,a,b) for (int i=a;i<=b;i++)
    #define mes(a,b) memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define LL long long
    using namespace std;
    const int N=110,MAX=1000100;
    const double eps=1e-8;
    
    struct Point
    {
        double x,y;
    }p[N],stack[N];
    
    int isZero(double x) {      //x是否为0,还是不明白为什么要引入eps
        return (x>0?x:-x)<eps;
    }
    
    double crossProd(Point A,Point B,Point C) {     //叉积,这样写即A->B到A->C逆时针为正
        return (B.x-A.x)*(C.y-A.y)-(B.y-A.y)*(C.x-A.x);
    }
    
    double dis(Point A,Point B) {
        return sqrt((B.x-A.x)*(B.x-A.x)+(B.y-A.y)*(B.y-A.y));
    }
    
    //以最左下的点为基准点,其他各点(逆时针方向)以极角从小到大的排序规则
    int cmp(const void *a,const void *b) {    //这里表示*a在*b后
        Point *c=(Point *)a, *d=(Point *)b;
        double k=crossProd(p[1],*c,*d);     //极角大小转化为求叉乘
        if(k<eps||isZero(k)&&dis(p[1],*d)<dis(p[1],*c)) return 1;
        return -1;
    }
    
    int n;
    double Graham()
    {
        int mi=1;
        double mx=p[1].x, my=p[1].y;
        FF(i,2,n) {     //找到最左下点
            if(my>p[i].y||my==p[i].y&&mx>p[i].x) {
                mi=i, my=p[i].y, mx=p[i].x;
            }
        }
        p[0]=p[mi], p[mi]=p[1], p[1]=p[0];  //最左下点要换到p开头,不能让它和它自己比
        qsort(p+2,n-1,sizeof(Point),cmp);
        stack[1]=p[1], stack[2]=p[2], stack[3]=p[3];
        p[n+1]=p[1];    //在结尾加最左下点为结束点,一开始没加,直接在len加了一个dis(p[1],p[n]),这样忽略了很多
        int top=3;
        for(int i=4; i<=n+1; i++) {
            //加入一个点后,向右偏拐或共线,则上一个点不在凸包内,则--top,该过程直到不向右偏拐或没有三点共线的点
            while(crossProd(stack[top-1],stack[top],p[i])<eps&&top>=3) top--;
            stack[++top]=p[i];
        }
        double len=0;
        F(i,1,top) {
            len+=dis(stack[i],stack[i+1]);
        }
        return len;
    }
    
    int main()
    {
        while(scanf("%d",&n)!=EOF,n) {
            FF(i,1,n) {
                scanf("%lf%lf",&p[i].x,&p[i].y);
            }
            if(n==1) printf("0.00
    ");
            else if(n==2) printf("%.2lf
    ",dis(p[1],p[2]));
            else {
                printf("%.2lf
    ",Graham());       //这里printf用G++11竟然输出0
            }
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    HttpClient POST/GET方法
    Selenium+Java(十一)Selenium窗口切换
    Selenium+Java(十)Selenium常用方法
    Selenium+Java(九)Selenium键盘与鼠标事件
    Selenium+Java(八)Selenium下拉框处理
    Selenium+Java(七)Selenium对话框的处理
    Selenium+Java(六)Selenium 强制等待、显式等待、隐实等待
    [java]对象创建的过程
    [正则表达式] 表达式使用记录
    【Mysql】主从复制
  • 原文地址:https://www.cnblogs.com/sbfhy/p/6021584.html
Copyright © 2011-2022 走看看