• 旋转卡壳——模板(对踵点)


    这东西学了我大概两天吧。。其实不应该学这么久的,但是这两天有点小困,然后学习时间被削了很多(QwQ)

    说几个坑点。

    - 对于题目不保证有凸包的情况,要选用左下角的点,而非单纯的最下边的点构造凸包。

    - 对于凸包中只有(1/2)个点的情况,要注意特殊判断。

    算法流程就比较简单了。先构造一个凸包,然后利用对踵点都是逆时针跑(类似于两把尺子卡着凸包转)的原理,每次判断到当前直线距离最远的点,更新当前对踵点即可。

    例题 【luogu P1452】Beauty contest

    #include <bits/stdc++.h>
    #define N 50010
    using namespace std;
    
    struct point {
        int x, y;
    }arr[N], hull[N];
    
    int n, top;
    
    int cross (point u1, point u2, point v1, point v2) {
        return (u2.x - u1.x) * (v2.y - v1.y) - (u2.y - u1.y) * (v2.x - v1.x);
    }
    
    int point_dis (point u, point v) {
        return (v.x - u.x) * (v.x - u.x) + (v.y - u.y) * (v.y - u.y);
    }
    
    bool cmp (point lhs, point rhs) {
        if (cross (arr[1], lhs, arr[1], rhs) < 0) return false;
        if (cross (arr[1], lhs, arr[1], rhs) > 0) return true;
        return point_dis (arr[1], lhs) < point_dis (arr[1], rhs);
    }
    
    void get_hull () {
        sort (arr + 2, arr + 1 + n, cmp);
        hull[++top] = arr[1];
        for (int i = 2; i <= n; ++i) {
            while (top > 1 && cross (hull[top - 1], hull[top], hull[top], arr[i]) <= 0) --top;
            hull[++top] = arr[i];
        }
        hull[top + 1] = arr[1];
    }
    
    int get_ans () {
        if (top == 1) return 0;
        if (top == 2) return point_dis (hull[1], hull[2]);
        int v = 2, ans = 0;
        for (int u = 1; u <= top; ++u) {
            while (cross (hull[u], hull[u + 1], hull[u + 1], hull[v]) <=
                   cross (hull[u], hull[u + 1], hull[u + 1], hull[v + 1])) {
                v = v == top ? 1 : v + 1;
            }
            ans = max (ans, max (point_dis (hull[u], hull[v]), point_dis (hull[u + 1], hull[v])));
        }
        return ans;
    }
    
    int main () {
        cin >> n;
        for (int i = 1; i <= n; ++i) {
            cin >> arr[i].x >> arr[i].y;
            if (arr[i].y < arr[1].y || (arr[i].y == arr[1].y && arr[i].x < arr[1].x)) {
                swap (arr[i], arr[1]);
            }
        }
        get_hull ();
        cout << get_ans () << endl;
    }
    
    
  • 相关阅读:
    9个数中取最大值最小值速度问题
    ubuntu 12.04安装git 1.8.11
    <转>Win7资源管理器更新后不断重启解决方案
    windows下安装安卓开发环境和NDK支持
    饱和算法
    bzip21.0.6
    《转》GetFileTitle与文件扩展名是否显示有关
    Ubuntu设置环境变量PATH的三种方法 <转>
    ubuntu下使用脚本交叉编译windows下使用的ffmpeg
    UnxUtils windows下linux命令
  • 原文地址:https://www.cnblogs.com/maomao9173/p/10395499.html
Copyright © 2020-2023  润新知