zoukankan      html  css  js  c++  java
  • HDU 1392 Surround the Trees(凸包模板)

    http://acm.hdu.edu.cn/showproblem.php?pid=1392

    这题是凸包的模板题目……看算法后纯原创+_+

    思路:

    1:在输入的时候就保留住最下面而又靠左的点,这点为起点p0;设置hash表为是否访问过该点,因为结束标志是找到下一个顶点为p0,所以初始化时不可以将p0点赋为已经访问

    做n个循环,pi保留下一个要开始求凸包边的点

    2:循环从P0开始,设置点Pj也是p0,然后

    3:将j从0开始,找到所以的未访问的点,依次和pi,pj进行叉乘,(j-pi)×(pj-pi),大于0时j在pj顺时针方向,小于0就在逆时针方向。等于0时则共线,返回距离较远的那个点,结果保留在pj里面。

    4:所有点测试完则把更新好了的pj放在pi里,这是下一个凸包的顶点;并记录至今为止的总距离

    5:如果pi已经是p0了,就可以输出了,否则在从2继续。

    这题里的n=1,n=2,以及共线,都是特殊情况,要注意

    #include<stdio.h>
    #include<math.h>
    struct node
    {
      double x,y;
    }p[110];
    int hash[110],flag;
    double distance(int a,int b)//求两点之间距离
    {
        return sqrt(pow(p[a].x-p[b].x,2)+pow(p[a].y-p[b].y,2));
    }
    int cross_product(int a,int b,int c)//求两向量叉乘
    {
        double x1,y1,x2,y2;
        x1=p[a].x-p[c].x;
        y1=p[a].y-p[c].y;
        x2=p[b].x-p[c].x;
        y2=p[b].y-p[c].y;
        if(x1*y2-x2*y1>0)
         {
            flag=1;
            return a;
         }
        else if(fabs(x1*y2-x2*y1)<1e-6)
        {
            if(distance(a,c)>distance(b,c))return a;
            else return b;
        }
        return b;
    }
    int main()
    {
        int n,i,p0,j,pj,pi;
        double x0,y0,sum;
        while(scanf("%d",&n),n)
        {
            sum=0;
            flag=0;
            x0=y0=999999;
            for(i=0;i<n;i++)
            {
                hash[i]=0;
                scanf("%lf%lf",&p[i].x,&p[i].y);
                if(p[i].y<y0||(p[i].y==y0&&p[i].x<x0))
                {
                    x0=p[i].x;
                    y0=p[i].y;
                    p0=i;
                }
            }
            if(n==1)
            {
                printf("0.00
    ");
                continue;
            }
            if(n==2)
            {
                printf("%.2lf
    ",distance(0,1));
                continue;
            }
                pi=p0;
            for(i=0;i<n;i++)
            {
                pj=p0;
                //while(pj==p0||(pj<n&&hash[pj]))pj++;
                for(j=0;j<n;j++)
                {
                      pj=cross_product(j,pj,pi);
                }
                hash[pj]=1;
                sum=sum+distance(pi,pj);
                pi=pj;
                if(pj==p0)break;
            }
            if(flag)
            printf("%.2lf
    ",sum);
            else printf("%.2lf
    ",sum/2);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    记录-java(jxl) Excel导入数据库
    记录--Gson、json转实体类、类转json
    记录--java获取网络资源(图片、音频等)保存本地
    记录--指定路径复制文件到另一个路径
    记录-java执行请求的URL
    记录-Hibernate+servlet实现简单的增、删、查、改
    我的学习之路_第二十八章_JQuery 和validator插件
    我的学习之路_第二十七章_jQuery
    我的学习之路_第二十六章_javaScript(2)
    我的学习之路_第二十五_javaScript
  • 原文地址:https://www.cnblogs.com/huzhenbo113/p/3272312.html
Copyright © 2011-2022 走看看