zoukankan      html  css  js  c++  java
  • hdu 3934 Summer holiday (凸包+旋转卡壳)

    Problem - 3934

      晚上为了演示给师弟看水平序的凸包是多么的好写,于是就随便找了一题凸包,25min居然1y掉了。。

    代码如下:

     1 #include <cmath>
     2 #include <cstdio>
     3 #include <iostream>
     4 #include <cstring>
     5 #include <algorithm>
     6 
     7 using namespace std;
     8 
     9 const int N = 1111111;
    10 const double EPS = 1e-8;
    11 inline int sgn(double x) { return (x > EPS) - (x < -EPS);}
    12 struct Point {
    13     double x, y;
    14     Point() {}
    15     Point(double x, double y) : x(x), y(y) {}
    16     Point operator - (Point a) { return Point(x - a.x, y - a.y);}
    17     bool operator < (Point a) const { return sgn(x - a.x) < 0 || sgn(x - a.x) == 0 && y < a.y;}
    18 } ;
    19 
    20 inline double cross(Point a, Point b) { return a.x * b.y - a.y * b.x;}
    21 
    22 int andrew(Point *pt, Point *ch, int n) {
    23     sort(pt, pt + n);
    24     int m = 0;
    25     for (int i = 0; i < n; i++) {
    26         while (m > 1 && sgn(cross(pt[i] - ch[m - 2], ch[m - 1] - ch[m - 2])) <= 0) m--;
    27         ch[m++] = pt[i];
    28     }
    29     int k = m;
    30     for (int i = n - 2; i >= 0; i--) {
    31         while (m > k && sgn(cross(pt[i] - ch[m - 2], ch[m - 1] - ch[m - 2])) <= 0) m--;
    32         ch[m++] = pt[i];
    33     }
    34     if (n > 1) m--;
    35     return m;
    36 }
    37 
    38 Point ch[N], pt[N];
    39 inline double area(Point a, Point b, Point c) { return fabs(cross(c - a, b - a));}
    40 
    41 double work(Point *pt, int n) {
    42     if (n < 3) return 0;
    43     double ans = area(pt[0], pt[1], pt[2]);
    44     for (int i = 0, j = 1, k = 2; i < n; i++) {
    45         while (true) {
    46             bool df = false;
    47             if (i == j) j = (j + 1) % n;
    48             if (j == k) k = (k + 1) % n;
    49             while (true) {
    50                 double a1 = area(pt[i], pt[j], pt[k]);
    51                 double a2 = area(pt[i], pt[j], pt[(k + 1) % n]);
    52                 ans = max(ans, a1);
    53                 if (sgn(a1 - a2) > 0) break; 
    54                 k = (k + 1) % n;
    55                 df = true;
    56             }
    57             while (true) {
    58                 double a1 = area(pt[i], pt[j], pt[k]);
    59                 double a2 = area(pt[i], pt[(j + 1) % n], pt[k % n]);
    60                 ans = max(ans, a1);
    61                 if (sgn(a1 - a2) > 0) break; 
    62                 j = (j + 1) % n;
    63                 df = true;
    64             }
    65             if (!df) break;
    66         }
    67     }
    68     return ans / 2;
    69 }
    70 
    71 int main() {
    72     int n;
    73     while (~scanf("%d", &n)) {
    74         for (int i = 0; i < n; i++) scanf("%lf%lf", &pt[i].x, &pt[i].y);
    75         n = andrew(pt, ch, n);
    76         printf("%.2f
    ", work(ch, n));
    77     }
    78     return 0;
    79 }
    View Code

    ——written by Lyon

  • 相关阅读:
    解决ListView异步加载数据之后不能点击的问题
    android点击实现图片放大缩小 java技术博客
    关于 数据文件自增长 的一点理解
    RAC 实例不能启动 ORA1589 signalled during ALTER DATABASE OPEN
    Linux 超级用户的权利
    RAC 实例 迁移到 单实例 使用导出导入
    Shell 基本语法
    Linux 开机引导与关机过程
    RAC 实例不能启动 ORA1589 signalled during ALTER DATABASE OPEN
    Oracle RAC + Data Guard 环境搭建
  • 原文地址:https://www.cnblogs.com/LyonLys/p/hdu_3934_Lyon.html
Copyright © 2011-2022 走看看