题解报告:hdu 1392 Surround the Trees(凸包入门)
Problem Description
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
Zero at line for number of trees terminates the input for your program.
Output
Sample Input
Sample Output


#include<iostream>
#include<string.h>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=;
const double PI=acos(-1.0);
struct node{int x,y;};
node vex[maxn];//存入所有坐标点
node stackk[maxn];//凸包中所有的点
bool cmp1(node a,node b){//按点的坐标排序
if(a.y==b.y)return a.x<b.x;//如果纵坐标相同,则按横坐标升序排
else return a.y<b.y;//否则按纵坐标升序排
}
bool cmp2(node a,node b){//以基点为坐标原点,极角按升序排,这里可用atan2函数或者叉积来进行极角排序,但是用atan2函数来排序效率高时间快,不过精度比叉积低
double A=atan2(a.y-stackk[].y,a.x-stackk[].x);//返回的是原点至点(x,y)的方位角,即与x轴的夹角
double B=atan2(b.y-stackk[].y,b.x-stackk[].x);
if(A!=B)return A<B;//逆时针方向为正值,极角小的排在前面
else return a.x<b.x;//如果极角相同,则横坐标在前面的靠前排列
}
int cross(node p0,node p1,node p2){//计算两个向量a、b(a=(x1,y1),b=(x2,y2))的叉积公式:a×b=x1y2-x2y1 ===> p0p1=(x1-x0,y1-y0),p0p2=(x2-x0,y2-y0)
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
double dis(node a,node b){//计算两点之间的距离
return sqrt((a.x-b.x)*(a.x-b.x)*1.0+(a.y-b.y)*(a.y-b.y));
}
int main(){
int t;
while(~scanf("%d",&t)&&t){
for(int i=;i<t;++i)//输入t个点
scanf("%d%d",&vex[i].x,&vex[i].y);
if(t==)printf("%.2f\n",0.00);//如果只有一个点,则周长为0.00
else if(t==)printf("%.2f\n",dis(vex[],vex[]));//如果只有两个点,则周长为两个点的距离
else{
memset(stackk,,sizeof(stackk));//清0
sort(vex,vex+t,cmp1);//先按坐标点的位置进行排序
stackk[]=vex[];//取出基点
sort(vex+,vex+t,cmp2);//将剩下的坐标点按极角进行排序,以基点为坐标原点
stackk[]=vex[];//将凸包中的第二个点存入凸集中
int top=;//当前凸包中拥有点的个数为top+1
for(int i=;i<t;++i){//不断地找外围的坐标点
while(top>&&cross(stackk[top-],stackk[top],vex[i])<=)top--;//如果叉积为负数或0(0表示两向量共线),则弹出栈顶元素
//虽然第2个凸点显然是最外围的一点,但加上top>0保证了栈中至少有2个凸点
stackk[++top]=vex[i];
}
double s=;
for(int i=;i<=top;++i)//计算凸包的周长
s+=dis(stackk[i-],stackk[i]);
s+=dis(stackk[top],vex[]);//最后一个点和第一个点之间的距离
printf("%.2f\n",s);
}
}
return ;
}
AC代码二(31ms):Andrew算法,一次坐标排序,两次构造成一个完整的凸包,时间复杂度为O(nlogn),但实际上比Graham扫描算法快很多,具体讲解-->凸包解法总结。
#include<iostream>
#include<string.h>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=;
const double PI=acos(-1.0);
struct node{int x,y;}vex[maxn],stackk[maxn];
bool cmp(node a,node b){//按点的坐标排序
return (a.y<b.y)||(a.y==b.y&&a.x<b.x);
}
int cross(node p0,node p1,node p2){
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
double dis(node a,node b){
return sqrt((a.x-b.x)*(a.x-b.x)*1.0+(a.y-b.y)*(a.y-b.y));
}
int main(){
int t;
while(~scanf("%d",&t)&&t){
for(int i=;i<t;++i)//输入t个点
scanf("%d%d",&vex[i].x,&vex[i].y);
if(t==)printf("%.2f\n",0.00);
else if(t==)printf("%.2f\n",dis(vex[],vex[]));
else{
memset(stackk,,sizeof(stackk));//清0
sort(vex,vex+t,cmp);//一次坐标排序,两次构造成一个完整的凸包
int top=-;
for(int i=;i<t;++i){//构造凸包下侧
while(top>&&cross(stackk[top-],stackk[top],vex[i])<=)top--;
stackk[++top]=vex[i];
}
for(int i=t-,k=top;i>=;--i){//构造凸包上侧,默认此时凸包中只有一个顶点n-1,因此top要大于k,起点再被包含一次且一定被包含
while(top>k&&cross(stackk[top-],stackk[top],vex[i])<=)top--;
stackk[++top]=vex[i];
}
double s=;
for(int i=;i<=top;++i)//计算凸包周长
s+=dis(stackk[i-],stackk[i]);
printf("%.2f\n",s);
}
}
return ;
}
题解报告:hdu 1392 Surround the Trees(凸包入门)的更多相关文章
- HDU - 1392 Surround the Trees (凸包)
Surround the Trees:http://acm.hdu.edu.cn/showproblem.php?pid=1392 题意: 在给定点中找到凸包,计算这个凸包的周长. 思路: 这道题找出 ...
- HDU 1392 Surround the Trees (凸包周长)
题目链接:HDU 1392 Problem Description There are a lot of trees in an area. A peasant wants to buy a rope ...
- 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 凸包裸题
Surround the Trees Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- HDU 1392 Surround the Trees(凸包*计算几何)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1392 这里介绍一种求凸包的算法:Graham.(相对于其它人的解释可能会有一些出入,但大体都属于这个算 ...
- 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 此题讨论区里大喊有坑,原谅我没有仔细读题还跳过了坑点. 题意:平面上有n棵树,选一些树用绳子围成一个包围圈,使得所有的树都在这个圈内. 思路:简单凸包入门题,凸包 ...
随机推荐
- 电脑突然死机,编译报错dll缺少依赖项
由于ASP.NET缓存没更新的问题(我的就是这个问题.电脑突然死机导致的). 把这个文件夹下的文件所有删除C:\Windows\Microsoft.NET\Framework\v2.0.50727\T ...
- Shell hook
[目的]实现 ll -as +hook+ clear Shell脚本及钩子 - CSDN博客 https://blog.csdn.net/shengzhu1/article/details ...
- 前端遇上Go: 静态资源增量更新的新实践
前端遇上Go: 静态资源增量更新的新实践https://mp.weixin.qq.com/s/hCqQW1F8FngPPGZAisAWUg 前端遇上Go: 静态资源增量更新的新实践 原创: 洋河 美团 ...
- h5 getUserMedia error PermissionDeniedError
HTML5 在使用非 localhost 地址访问时打开摄像头失败 .报getUserMedia error PermissionDeniedError,火狐下是可以正常调取的. 需要https: 火 ...
- poj 1195 Mobile phones 解题报告
题目链接:http://poj.org/problem?id=1195 题目意思:有一部 mobie phone 基站,它的面积被分成一个个小正方形(1 * 1 的大小),所有的小正方形的面积构成了一 ...
- DGA聚类 使用DBScan
features = sc.parallelize(data_group[idx]).map(lambda x: (x.host_ip+'^'+x.domain, 1)).reduceByKey(op ...
- lock的两种方式
假设现在我们有100个数据项可以读写.有若干个线程,任何一个线程可能对任何一个数据项尽心读写. 但是,如果不同的线程在对同一个数据项进行读写,就可能发生错误.需要使用lock进行控制. 比如线程x要对 ...
- HDU 1711(KMP)字符串匹配
链接 HDU 1711 Number Sequence KMP 算法 我以自己理解写的,写的不对,不明白的地方海王子出来,一起共同学习: 字符串匹配 就是KMP,一般思想,用一个for循环找开头 ...
- oracle自动表分析
oracle 表的统计信息,跟他的执行计划很有关联 执行计划的正常是否,跟SQL的执行速度很有关系 首先讲解一下如何查看一个数据库的是否开启自动统计分析 1.查看参数:STATISTICS_LEVEL ...
- ubuntu中使用apt-get安装zbar
apt-get是linux中常用的shell命令,适用于deb包管理式的操作系统,主要用于自动从互联网的软件仓库中搜索.安装.升级.卸载软件或操作系统.apt-get命令一般需要root权限执行,所以 ...