zoukankan      html  css  js  c++  java
  • HDU 1392 Surround the Trees(几何 凸包模板)

    http://acm.hdu.edu.cn/showproblem.php?pid=1392

    题目大意:

      二维平面给定n个点,用一条最短的绳子将所有的点都围在里面,求绳子的长度。

    解题思路:

      凸包的模板。凸包有很多的算法。这里用Adrew。

      注意这几组测试数据

      1

      1 1

      3

      0 0

      1 0

      2 0

      输出数据

      0.00

      2.00

     1 #include<cmath>
     2 #include<cstdio>
     3 #include<algorithm>
     4 using namespace std;
     5 
     6 #define MAXN 100+10
     7 
     8 struct Point{
     9     double x, y;
    10 
    11     Point(double x = 0, double y = 0): x(x), y(y){}
    12 
    13     void scan(){
    14         scanf("%lf %lf", &x, &y);
    15     }
    16 };
    17 
    18 typedef Point Vector;
    19 
    20 Vector operator - (Vector A, Vector B){
    21     return Vector(A.x - B.x, A.y - B.y);
    22 }
    23 
    24 double dot(Vector A, Vector B){//点乘
    25     return A.x * B.x + A.y * B.y;
    26 }
    27 double length(Vector A){//向量模
    28     return sqrt(dot(A, A));
    29 }
    30 double cross(Vector A, Vector B){//叉乘
    31     return A.x * B.y - A.y * B.x;
    32 }
    33 
    34 int n;
    35 Point p[MAXN], stack[MAXN];
    36 
    37 bool input(){
    38     scanf("%d", &n);
    39     if(n == 0) return false;
    40     for(int i = 0; i < n; ++i){
    41         p[i].scan();
    42     }
    43     return true;
    44 }
    45 
    46 bool cmp(Point A, Point B){
    47     return A.x < B.x || (A.x == B.x && A.y < B.y);
    48 }
    49 
    50 int convex_hull(){//Adrew算法 求凸包
    51     sort(p, p + n, cmp);
    52 
    53     int m = 0;
    54     for(int i = 0; i < n; ++i){
    55         while(m > 1 && cross(stack[m - 1] - stack[m - 2], p[i] - stack[m - 2]) <= 0) --m;
    56         stack[m ++] = p[i];
    57     }
    58     int k = m;
    59     for(int i = n - 1; i >= 0; --i){
    60         while(m > k && cross(stack[m - 1] - stack[m - 2], p[i] - stack[m - 2]) <= 0) --m;
    61         stack[m ++] = p[i];
    62     }
    63     if(n > 1) --m;
    64     return m;
    65 }
    66 
    67 void solve(){
    68     n = convex_hull();
    69     if(n == 1){//当只有一个点时,绳子长度为0
    70         puts("0.00");
    71         return ;
    72     }
    73     if(n == 2){//当只有两个点时,绳子长度为两点之间的长度
    74         printf("%.2lf
    ", length(stack[0] - stack[1]));
    75         return ;
    76     }
    77     double ans = 0;//绳子的累加长度
    78     stack[n] = stack[0];//为了算第n点到第1点的距离
    79     for(int i = 0; i < n; ++i){
    80         ans += length(stack[i] - stack[i + 1]);
    81     }
    82     printf("%.2lf
    ", ans);
    83 }
    84 
    85 int main(){
    86     while(input()){
    87         solve();
    88     }
    89     return 0;
    90 }
  • 相关阅读:
    [BZOJ1303][CQOI2009]中位数图
    [BZOJ1192][HNOI2006]鬼谷子的钱袋
    9.5题解
    9.3题解
    9.2题解
    9.1题解
    8.29题解
    8.28题解
    8.23<2>题解
    8.23<1>题解
  • 原文地址:https://www.cnblogs.com/xuqiulin/p/HDU1392.html
Copyright © 2011-2022 走看看