Problem Description

There are a lot of trees in an area. A peasant wants to buy a rope to surround all these trees. So at first he must know the minimal required length of the rope. However, he does not know how to calculate it. Can you help him?

The diameter and length of the trees are omitted, which means a tree can be seen as a point. The thickness of the rope is also omitted which means a rope can be seen as a line.

There are no more than 100 trees.

Input

The input contains one or more data sets. At first line of each input data set is number of trees in this data set, it is followed by series of coordinates of the trees. Each coordinate is a positive integer pair, and each integer is less than 32767. Each pair is separated by blank.

Zero at line for number of trees terminates the input for your program.

Output

The minimal length of the rope. The precision should be 10^-2.

Sample Input

9
12 7
24 9
30 5
41 9
80 7
50 87
22 9
45 1
50 7
0

Sample Output

243.06

Source

Asia 1997, Shanghai (Mainland China)


思路

这就是找最小凸包并求其周长的过程,可以采用Graham算法,具体步骤如下:

  • 读入一系列坐标并找到y坐标最小的坐标设置为\(p_0\)(如果x坐标相同就找x最小的)
  • 对除了\(p_0\)以外的点按照逆时针以相对p0的极角排序,相同极角的点则保留一个离\(p_0\)最远的点
  • 设置一个栈,前三个候选点先入栈,接下来让剩下的点一一入栈,去掉所有非左转的情况,由此,栈里的点就是凸包的点

具体看注释

代码

#include<bits/stdc++.h>
using namespace std;
struct point
{
double x,y;
}a[110]; double dis(point a,point b)
{
return sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) );
} double crossMult(point a, point n1, point n2)
{
return (n1.x-a.x)*(n2.y-a.y) - (n1.y-a.y)*(n2.x-a.x);
} //叉积,以a为基 bool cmp(point n1, point n2)
{
double k = crossMult(a[1],n1,n2); //叉积
if( k>0 ) return true; //叉积>0则说明a在b的顺时针方向上
else
{
if( k==0 && dis(a[1],n1) < dis(a[1],n2) ) //叉积为0说明a和b在同一条直线上,且更远
return true;
}
return false;
} void sortByAngel(int n)
{
point tmp;
int k = 1;
for(int i=2; i<=n; i++)
{
if( a[i].y < a[k].y || a[i].y == a[k].y && a[i].x < a[k].x)
k = i;
} //找出p0
tmp = a[1];
a[1] = a[k];
a[k] = tmp;
sort(a+2, a+n+1,cmp); //对除了p0以外的点逆时针以相对p0的极角进行排序
} double Graham(int n)
{
sortByAngel(n) ;
point stack[110];
double sum = 0.0;
a[n+1] = a[1];
stack[1] = a[1]; stack[2] = a[2]; stack[3] = a[3];
int top = 3;//指向栈顶
for(int i=4;i<=n+1;i++) //这里是遍历到n+1,因为要回到最初的点
{
while( (crossMult(stack[top-1], stack[top], a[i])<=0) &&
top >= 3) top--; //保证是左转而且栈里面至少要有2个点(后面才能做叉积)
top++;
stack[top] = a[i];
}
for(int i=1;i<top;i++)//这里i<top即可,因为后面要访问的是stack[i],stack[i+1]
{
sum += dis(stack[i],stack[i+1]);
}
return sum;
} int main()
{
int n;
while(cin>>n)
{
if(0==n) break;
for(int i=1;i<=n;i++)
cin >> a[i].x >> a[i].y; if(1==n)
cout << "0.00" << endl;
else if(2==n)
printf("%.2lf\n",dis(a[1],a[2]));
else
{
double ans = Graham(n);
printf("%.2lf\n",ans);
}
}
return 0;
}

Hdoj 1392.Surround the Trees 题解的更多相关文章

  1. HDU 1392 Surround the Trees(凸包入门)

    Surround the Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  2. HDU - 1392 Surround the Trees (凸包)

    Surround the Trees:http://acm.hdu.edu.cn/showproblem.php?pid=1392 题意: 在给定点中找到凸包,计算这个凸包的周长. 思路: 这道题找出 ...

  3. hdu 1392 Surround the Trees 凸包裸题

    Surround the Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  4. hdu 1392 Surround the Trees 凸包模板

    Surround the Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  5. HDUJ 1392 Surround the Trees 凸包

    Surround the Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  6. hdu 1392:Surround the Trees(计算几何,求凸包周长)

    Surround the Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  7. hdu 1392 Surround the Trees (凸包)

    Surround the Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  8. 题解报告:hdu 1392 Surround the Trees(凸包入门)

    Problem Description There are a lot of trees in an area. A peasant wants to buy a rope to surround a ...

  9. HDU 1392 Surround the Trees(凸包)题解

    题意:给一堆二维的点,问你最少用多少距离能把这些点都围起来 思路: 凸包: 我们先找到所有点中最左下角的点p1,这个点绝对在凸包上.接下来对剩余点按照相对p1的角度升序排序,角度一样按距离升序排序.因 ...

随机推荐

  1. 合并dll文件

    在使用VS进行.Net编程时,出现了一个奇怪的现象. 在一个类库项目中导入了dll库A后,再导入A的两个依赖项(dll库)B和C,执行“生成”操作时,出现错误信息,提示B和C的库版本与A所需的不一致. ...

  2. hadoop:如何运行自带wordcount

    1.在linux系统创建文件 vi aa.txt   --------i 进行编辑  输入  内容(多个单词例如:aa bb cc aa) 2.在HDFS上面创建文件夹 hdfs dfs -mkdir ...

  3. jmeter之批量修改请求路径

    今天工作时碰到一个问题:测试环境中由于tomcat没指定webapps下的文件夹名,导致tomcat使用了webapps下默认的文件夹名,而我的jmeter脚本都已经做出来了,一共83个接口,挨个改路 ...

  4. 阿里云ECS服务器云监控(cloudmonitor)Go语言版本插件安装卸载与维护

    云监控Go语言版本插件安装_主机监控_用户指南_云监控-阿里云https://help.aliyun.com/document_detail/97929.html 云监控cloudmonitor 1. ...

  5. Java Profiling & Profilers

    A Guide to Java Profilers | Baeldunghttps://www.baeldung.com/java-profilers 常用 Java Profiling 工具的分析与 ...

  6. 容错处理try

    var num = 90; try{ console.log( num + 100 ); consolel.log(aaa); }catch(e){ console.log("如果程序中有异 ...

  7. [转帖]IP /TCP协议及握手过程和数据包格式中级详解

    IP /TCP协议及握手过程和数据包格式中级详解 https://www.toutiao.com/a6665292902458982926/ 写的挺好的 其实 一直没闹明白 网络好 广播地址 还有 网 ...

  8. web项目中的监听器,过滤器以及自定义servlet的执行顺序

    可以看到web容器一启动就会实例化监听器的contextInitialized(ServletContextEvent event)方法,然后是过滤器的init()方法,最后在用户访问web应用的 时 ...

  9. python之路--内置常用模块

    一 . 简单的了解模块 你写的每一个py文件都是一个模块. 还有一些我们一直在使用的模块. buildins  内置模块. print, input. random  主要是和随机相关的的内容 ran ...

  10. IBM rational rose画时序图软件破解安装

    上边这个链接是开头的安装步骤,照着链接中的步骤安装完之后,接下来看下边. 1.然后安装完成打开软件“IBM Rational License Keyadministrator”.出现下图:选中第二项“ ...