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. Win10系统如何安装Linux Mint

    导读 随着windows10系统免费升级期限的靠近,越来越多朋友都将自己的电脑系统升级到了win10正式版.今天,小编就要在这里为大家分享Windows10系统安装Linux Mint的方法,希望能够 ...

  2. 自己实现数据结构系列五---BinarySearchTree

    一.二分搜索树: 1.代码: public class BST<E extends Comparable<E>> { private class Node{ public E ...

  3. Java 读取配置文件数据

    Properties类 Properties类,是一个工具类,包含在java.util包中. 功能:可以保存持久的属性,通常用来读取配置文件或者属性文件,将文件中的数据读入properties对象中, ...

  4. windows 内建环境变量

    PS C:\Windows> ls env: Name Value ---- ----- _NT_SYMBOL_PATH srv*C:\Users\vv\Documents\symbols AL ...

  5. Windows BAT 命令下del 与 rd 命令

    https://blog.csdn.net/jigetage/article/details/81180757 RD 与 DEL 命令 windows bat 目录和文件的删除处理. 命令:RD,删除 ...

  6. [转帖]Office全版本零售版转换VOL

    Office全版本零售版转换VOL https://blog.51cto.com/10981246/2062137 转成bat 执行 改天试试   @ECHO OFF&PUSHD %~DP0 ...

  7. Spring的Bean配置

    IOC和DI 网上概念很多,感兴趣可以去搜一搜,在这里我就给个比喻: IOC:以前我们买东西都要去商店买,用了IOC之后,我们只要在门口放个箱子, Spring就会给我相应商品,ಠᴗಠ 举个例子 cl ...

  8. 死锁问题分析(个人认为重点讲到了gap间隙锁,解决了我一些不明报死锁的问题)

    线上某服务时不时报出如下异常(大约一天二十多次):“Deadlock found when trying to get lock;”. Oh, My God! 是死锁问题.尽管报错不多,对性能目前看来 ...

  9. qtp 自动化测试---点滴 获取属性性/修改窗体标题

    1 GetROProperty获取对应属性值 value url (这里出错了) If Window("新增").WinObject("TRzDBEdit_10" ...

  10. QTP 自动化测试桌面程序--笔记(下拉选择、右键菜单、在控件仓库中查找对应的控件)

    0 在收集窗口控件信息时-最好将可输入的文字去掉,不然控件的名称按输入的文字标记 1 编辑时录制脚本-默认按当前显示的填入的数据标记控件 可以使用 tool-spy-查看控件的x,y 坐标,按坐标在学 ...