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

思路:

凸包:

我们先找到所有点中最左下角的点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. ABC3

    Sql Server http://www.cnblogs.com/sunxi/p/4600152.html http://blog.csdn.net/dmz1981/article/details/ ...

  2. <3>lua字符串

    1.字符串 <1>字符串相连/加法   .. local str = "abc" str = str .. 7 --字符串与数字相连 print(str) --abc7 ...

  3. <script> 属性crossorigin

    今日偶然见到如下代码: <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper. ...

  4. UIView常见方法

    - (void)addSubview:(UIView *)view; 添加一个子控件view   - (void)removeFromSuperview; 从父控件中移除 - (UIView *)vi ...

  5. css selectors tips

    from https://saucelabs.com/resources/articles/selenium-tips-css-selectorsSauce Labs uses cookies to ...

  6. Java Socket入门

    Java Socket底层采用TCP/IP协议通信,通信细节被封装,我们仅仅需要指定IP.端口,便能轻易地创建TCP或UDP连接,进行网络通信.数据的读写,可以使用我们熟悉的stream进行操作. T ...

  7. px-pt-dp-rem像素单位的换算问题

    px-pt-dp-rem像素单位的换算问题 dp 的意思从 MDPI 到 XXXHDPI 每单位物理尺寸的像素数越来越大.也就是说 mdpi 时 1dp = 1pxxxxhdpi 时 1dp = 4p ...

  8. 前端框架VUE----组件的创建

    vue的核心基础就是组件的使用,玩好了组件才能将前面学的基础更好的运用起来.组件的使用更使我们的项目解耦合.更加符合vue的设计思想MVVM. 那接下来就跟我看一下如何在一个Vue实例中使用组件吧! ...

  9. 前端框架VUE----指令

    一.什么是VUE? 它是构建用户界面的JavaScript框架(让它自动生成js,css,html等) 二.怎么使用VUE? 1.引入vue.js 2.展示HTML <div id=" ...

  10. Eloquent JavaScript #11# The Document Object Model

    索引 Notes js与html DOM 在DOM树中移动 在DOM中寻找元素 改变Document 创建节点 html元素属性 布局 style CSS选择器 动画 Exercises Build ...