题解报告: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棵树,选一些树用绳子围成一个包围圈,使得所有的树都在这个圈内. 思路:简单凸包入门题,凸包 ...
随机推荐
- HDOJ1002
#include <iostream>#include<stdio.h> using namespace std;int main(){ int T, count_T; cha ...
- JAVA学习第十九课(java程序的异常处理 (二))
异常处理的捕捉形式: 这是能够对异常进行针对性处理的方式 六.try.catch的理解 详细格式: try { //须要被检測异常的代码 } catch(异常类 变量)//改变量用于接受发生异常的对象 ...
- Python2.7安装教程
作者:zhanhailiang 日期:2014-11-16 [root@~/software]# yum install bzip* [root@~/software]# wget http://ww ...
- UI类继承关系图
- MIPS 指令集将在近期开源,RISC-V 阵营慌吗?
消息称,MIPS 指令集即将开源. eetimes 17 日报导,Wave Computing 公司表示,在明年第一季度发布最新 MIPS 指令集体系和 MIPS 最新内核 R6 的时候将开源 MIP ...
- linux地址映射1、2、3(⭐⭐⭐)
欢迎关注瘋耔新浪微博:http://weibo.com/cpjphone 一.线性映射与非线性映射 ...
- C++的学习 (此博客将一直补充更新下去,C++语法方面的内容不开新随笔了, *【语法学习】)
// #include <sstream> // stringstream 是 C++ 提供的另一个字串型的串流(stream)物件,包含在上述头文件中 // 先谈它在字符串处理方面的应用 ...
- bfs 邻接表
#include<stdio.h> #include<stdlib.h> #include<string.h> struct node { int date; st ...
- 织梦dedecms页面中增加二维码功能的实现方法
本文介绍了在dedecms中增加二维码功能的实现方法,有时需要在dedecms页面增加二维码,方便手机用户访问,有需要的朋友参考下. 本节内容: dedecms中增加二维码功能 1.打开/incl ...
- SILVERLIGHT实现对HTML DOM的访问
实现对HTML DOM的访问.Silverlight 2在命名空间System.Windows.Browser下内置了很多对于HTML DOM访问和操作的支持,我们最常用的一个对象是HtmlEleme ...