Hdoj 1392.Surround the Trees 题解
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 题解的更多相关文章
- HDU 1392 Surround the Trees(凸包入门)
Surround the Trees Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- HDU - 1392 Surround the Trees (凸包)
Surround the Trees:http://acm.hdu.edu.cn/showproblem.php?pid=1392 题意: 在给定点中找到凸包,计算这个凸包的周长. 思路: 这道题找出 ...
- hdu 1392 Surround the Trees 凸包裸题
Surround the Trees Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- hdu 1392 Surround the Trees 凸包模板
Surround the Trees Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- HDUJ 1392 Surround the Trees 凸包
Surround the Trees Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- hdu 1392:Surround the Trees(计算几何,求凸包周长)
Surround the Trees Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- hdu 1392 Surround the Trees (凸包)
Surround the Trees Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- 题解报告: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 ...
- HDU 1392 Surround the Trees(凸包)题解
题意:给一堆二维的点,问你最少用多少距离能把这些点都围起来 思路: 凸包: 我们先找到所有点中最左下角的点p1,这个点绝对在凸包上.接下来对剩余点按照相对p1的角度升序排序,角度一样按距离升序排序.因 ...
随机推荐
- p86商空间也是Banach空间
1.为什么要引入Zk? 2.为什么这个等式成立,和为什么要引入uk? 3.为什么为什么等于0? 属于M,则商空间是0元,p128最上面的第二个笔记
- 打开指定测试App的指定Activity
那究竟应该如何让appium去自动找到指定的APP和指定的Activity呢?想要打开指定的App,需要知道App的包名,同样想要打开指定Activity也需要知道其名,如何获取? 1.问公司的开发人 ...
- Django异常问题之Error: [WinError 10013] 以一种访问权限不允许的方式做了一个访问套接字的尝试。
一般情况下,我们启动Django项目时默认设置的端口为8000,当你听着酷狗音乐敲着代码,启动Django项目时忽然翻车了. 不要慌,那是酷狗抢先一步占用了8000端口,解决这个问题的方式就是修改端口 ...
- 1170 - BLOB/TEXT column 'CustomerName' used in key specification without a key length
[DTF] Data Transfer 企管宝_2_CRM start[DTF] Getting tables[DTF] Analyzing table: `CustomerInfo`[DTF] Ge ...
- 【Java基础】求出1-100之间偶数和
结果:
- spring IOC源码分析(ApplicationContext)
在上一篇文章中,我们以BeanFactory这条主线进行IOC的源码解析的,这里,将以ApplicationContext这条线进行分析.先看使用方法: @Test public void testA ...
- 判断浏览器是否支持H5
window.onload = function() { if (!window.applicationCache) { alert("请升级您的浏览器版本,你的浏览器不支持HTML5!&q ...
- 随机森林(Random Forest)
阅读目录 1 什么是随机森林? 2 随机森林的特点 3 随机森林的相关基础知识 4 随机森林的生成 5 袋外错误率(oob error) 6 随机森林工作原理解释的一个简单例子 7 随机森林的Pyth ...
- centos6.8安装JDK
1.检测当前系统安装jdk信息 rpm -qa | grep jdk 2.如果检查到有安装信息,则用sudo yum remove XXX(XXX代表上面查到的结果) 3.下载rpm包,安 ...
- SpringMVC配置三大组件
1.组件扫描器 使用组件扫描器省去在spring容器配置每个Controller类的繁琐. 使用<context:component-scan>自动扫描标记@Controller的控制器类 ...