题意:给一堆二维的点,问你最少用多少距离能把这些点都围起来

思路:

凸包:

我们先找到所有点中最左下角的点p1,这个点绝对在凸包上。接下来对剩余点按照相对p1的角度升序排序,角度一样按距离升序排序。因为凸包有一个特点,从最左下逆时针走,所有线都在当前这条向量的左边,根据这个特点我们进行判断。我们从栈顶拿出两个点s[top-1],s[top],所以如果s[top-1] -> p[i] 在 s[top-1] -> s[top] 右边,那么s[top]就不是凸包上一点,就这样一直判断下去。判断左右可以用叉乘。

参考:数学:凸包算法详解

模板(考虑n <= 2):

struct node{
double x, y;
}p[maxn], s[maxn];
int n, top;
double dis(node a, node b){
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
bool cmp(node a, node b){
double A = atan2((a.y - p[].y), (a.x - p[].x));
double B = atan2((b.y - p[].y), (b.x - p[].x));
if(A != B) return A < B;
else{
return dis(a, p[]) < dis(b, p[]);
}
}
double cross(node a, node b, node c){ //(a->b)X(a->c)
return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
}
void solve(){
int pos = ;
for(int i = ; i <= n; i++){
if(p[i].y < p[pos].y || (p[i].y == p[pos].y && p[i].x < p[pos].x)){
pos = i;
}
}
swap(p[], p[pos]);
sort(p + , p + n + , cmp);
s[] = p[], s[] = p[];
top = ;
for(int i = ; i <= n; i++){
while(top >= && cross(s[top - ], p[i], s[top]) >= ){ //向右转出栈
top--;
}
s[++top] = p[i];
}
}

代码:

#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
typedef long long ll;
using namespace std;
const int maxn = + ;
const int MOD = 1e9 + ;
const int INF = 0x3f3f3f3f;
struct node{
double x, y;
}p[maxn], s[maxn];
int n, top;
double dis(node a, node b){
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
bool cmp(node a, node b){
double A = atan2((a.y - p[].y), (a.x - p[].x));
double B = atan2((b.y - p[].y), (b.x - p[].x));
if(A != B) return A < B;
else{
return dis(a, p[]) < dis(b, p[]);
}
}
double cross(node a, node b, node c){ //(a->b)X(a->c)
return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
}
void solve(){
int pos = ;
for(int i = ; i <= n; i++){
if(p[i].y < p[pos].y || (p[i].y == p[pos].y && p[i].x < p[pos].x)){
pos = i;
}
}
swap(p[], p[pos]);
sort(p + , p + n + , cmp);
s[] = p[], s[] = p[];
top = ;
for(int i = ; i <= n; i++){
while(top >= && cross(s[top - ], p[i], s[top]) >= ){ //向左转出栈
top--;
}
s[++top] = p[i];
}
}
int main(){
while(~scanf("%d", &n) && n){
for(int i = ; i <= n; i++){
scanf("%lf%lf", &p[i].x, &p[i].y);
}
if(n == ){
printf("0.00\n");
continue;
}
if(n == ){
printf("%.2lf\n", dis(p[], p[]));
continue;
}
solve();
double ans = ;
for(int i = ; i < top; i++){
ans += dis(s[i], s[i + ]);
}
ans += dis(s[top], s[]);
printf("%.2lf\n", ans);
}
return ;
}

HDU 1392 Surround the Trees(凸包)题解的更多相关文章

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

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

  2. 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 ...

  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. hdu 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(凸包*计算几何)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1392 这里介绍一种求凸包的算法:Graham.(相对于其它人的解释可能会有一些出入,但大体都属于这个算 ...

  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(计算几何,求凸包周长)

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

  9. HDUJ 1392 Surround the Trees 凸包

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

  10. 题解报告: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 ...

随机推荐

  1. html5-新布局元素header,footer

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  2. 【转】Requests 官方中文文档 - 快速上手

    迫不及待了吗?本页内容为如何入门 Requests 提供了很好的指引.其假设你已经安装了 Requests.如果还没有,去安装一节看看吧. 首先,确认一下: Requests 已安装 Requests ...

  3. Java多线程-----创建线程的几种方式

       1.继承Thread类创建线程 定义Thread类的子类,并重写该类的run()方法,该方法的方法体就是线程需要完成的任务,run()方法也称为线程执行体 创建Thread子类的实例,也就是创建 ...

  4. 【Elasticsearch学习之一】Elasticsearch

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk8 一.概念ElasticSearch: 基于Lucene全文搜 ...

  5. Hive和sparksql中的dayofweek

    dayofweek在hive2.2.0开始支持 ,低版本的hive没有提供原生的dayofweek函数,有时需要用到的时候不甚方便.其实低版本的sparksql和hive中可用以下方式实现dayofw ...

  6. Base64图片编码原理,base64图片工具介绍,图片在线转换Base64

    Base64图片编码原理,base64图片工具介绍,图片在线转换Base64 DataURI 允许在HTML文档中嵌入小文件,可以使用 img 标签或 CSS 嵌入转换后的 Base64 编码,减少  ...

  7. 算法提高 P0101

    一个水分子的质量是3.0*10-23克,一夸脱水的质量是950克.写一个程序输入水的夸脱数n(0 <= n <= 1e10),然后输出水分子的总数.输入 109.43输出 3.465283 ...

  8. Codeforce 296A - Yaroslav and Permutations

    Yaroslav has an array that consists of n integers. In one second Yaroslav can swap two neighboring a ...

  9. P5015 标题统计

    P5015 标题统计 ‘   ’ 不等于空格,空格是个字符 代码: #include<iostream> #include<cstdio> #include<cmath& ...

  10. setfacl 设置文件访问控制列表

    setfacl 设置文件访问控制列表 用法: setfacl [-bkndRLP] { -m|-M|-x|-X ... } file ... 参数: -m, --modify=acl 更改文件的访问控 ...