HDU1392

原创 2012年03月24日 14:15:08

基础的计算几何题,求一个周长最小的,覆盖所有点集的多边形。明显是求凸包。求凸包先要做极角排序,这里不要用斜率做,否则会带来很多麻烦。用叉乘法,分别将两点,B,C与最低点A连接,若AB×AC<0,则B的极角大于C。这里说一下等于0的情况,也就是A,B,C共线,则令离A远的点极角大。然后就是入栈搜索,这一段略。最后,就是求多边形周长。特别的,若入栈使没有拐弯过,即所有点共线,要除2。

一下是程序:

#include <iostream>
#include <cmath>
#include <iomanip>

using namespace std;

int n;  

struct point
{
       int x;
       int y;
       point()
       {
              x=0;y=0;
       }
      
};

int check(point a,point b,point c)
{
     int x1,x2,y1,y2,r;
     x1=b.x-a.x;
     x2=c.x-a.x;
     y1=b.y-a.y;
     y2=c.y-a.y;
     r=x1*y2-x2*y1;
     return r;
}

double dis(point a,point b)
{
       double r;
       r=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
       r=sqrt(r);
       return r;
}

void anglesort(point* a)
{
     int i,j,r,flag;
     for (i=1;i<n-1;i++)
         for (j=i+1;j<n;j++)
         {
             flag=0;
             r=check(a[0],a[i],a[j]);
             if (r<0) flag=1;
             else if (r==0)
             {
                  if (dis(a[0],a[i])>dis(a[0],a[j])) flag=1;
             }
             if (flag)
             {
                      point tmp=a[i];
                      a[i]=a[j];
                      a[j]=tmp;
             }
         }
}

void input(point* a)
{
      int mi,i,mmin=10e8;
      for (i=0;i<n;i++)
      {
          scanf("%d%d",&a[i].x,&a[i].y);
          if (a[i].y<mmin)
          {
                           mmin=a[i].y;
                           mi=i;
          }
      }
      point tmp=a[mi];
      a[mi]=a[0];
      a[0]=tmp;
      a[n]=a[0];
}

void making(point* a,int* b,double &r)
{
     b[0]=0;b[1]=1;
     int top=1,s=2,t,i,flag=1;
     while (true)
     {
           int x=b[top-1],y=b[top];
           t=check(a[x],a[y],a[s]);
           if (t>=0)
           {
                    if (t!=0) flag=0;
                    b[++top]=s;
                    s++;
           }
           else top--;
           if (b[top]==n) break;
     }
     for (i=0;i<top;i++)
         r+=dis(a[b[i]],a[b[i+1]]);
     if (flag) r/=2.0;
}

int main()
{
    int i,j;
    double r;
    while (scanf("%d",&n))
    {
          r=0;
          if (n==0) break;
          point* a=new point[n+10];
          input(a);
          if (n==2) r=dis(a[0],a[1]);
          else
          {
               r=0;
               anglesort(a);  
               int* b=new int[n+10];
               memset(b,0,sizeof(b));
               making(a,b,r);
               delete []b;
          }
          cout<<fixed<<setprecision(2)<<r<<endl;
          delete []a;
    }
    return 0;
}

 

 

【计算几何初步-凸包-Jarvis步进法。】【HDU1392】Surround the Trees

【科普】什么是BestCoder?如何参加? Surround the Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limi...

HDU 1392 Surround the Trees(求凸包周长)

题目链接: HDU 1392 Surround the Trees 题意: 求凸包周长。 分析: 需要注意只有一个点时答案是0,只有两个点时答案是两点间距离。#include #inclu...
  • Ramay7
  • Ramay7
  • 2016年04月20日 00:09
  • 239

hdu 1392 Surround the Trees 凸包模板题

#include #include #include #include #include using namespace std; const int maxn=111; struct no...

hdu_1392_Surround the Trees(凸包)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1392 题意:求凸包,不知道的百度 题解:模版题 #include #include #inclu...

HDU1392+凸包

/* 几何 凸包 顺时针!!! */ #include #include #include #include #include #include //#include #incl...
  • xxx0624
  • xxx0624
  • 2013年08月18日 21:26
  • 631

hdu1392——凸包模板

http://acm.hdu.edu.cn/showproblem.php?pid=1392 type point=record x,y:longint; end; var ...

HDU1392 Surround the Trees(凸包模版题)

给你一个数n,代表一共有多少课树,然后给你n对点表示每棵树的坐标,要你求一个多边形能把所有的点包起来。...

ACM-计算几何之Surround the Trees——hdu1392

ACM 计算几何 Surround the Trees hdu1392 凸包周长

HDU 1392

这样不好。。。一天到晚就搞搞水题。。。 这题WA点就是凸包如果只有一个点的时候,输出0,两个点的时候输出距离 以上#include #include #include #include using...

HDU 1392 凸包入门题目,求周长

这题就是凸包入门题目,求凸包周长 #include #include #include #include #include using namespace std; const int m...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HDU1392
举报原因:
原因补充:

(最多只允许输入30个字)