• 旋转卡壳


    看了一些旋转卡壳的资料。理解的还是不深,推荐博客:http://blog.csdn.net/ACMaker

    POJ 2187

    裸凸包+旋转卡(qia)壳,O(n^2)的枚举也能过

    View Code
    //#pragma comment(linker,"/STACK:327680000,327680000")
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <set>
    #include <functional>
    #include <numeric>
    #include <sstream>
    #include <stack>
    #include <map>
    #include <queue>
    
    #define CL(arr, val)    memset(arr, val, sizeof(arr))
    #define REP(i, n)       for((i) = 0; (i) < (n); ++(i))
    #define FOR(i, l, h)    for((i) = (l); (i) <= (h); ++(i))
    #define FORD(i, h, l)   for((i) = (h); (i) >= (l); --(i))
    #define L(x)    (x) << 1
    #define R(x)    (x) << 1 | 1
    #define MID(l, r)   (l + r) >> 1
    #define Min(x, y)   (x) < (y) ? (x) : (y)
    #define Max(x, y)   (x) < (y) ? (y) : (x)
    #define E(x)        (1 << (x))
    #define iabs(x)     (x) < 0 ? -(x) : (x)
    #define OUT(x)  printf("%I64d\n", x)
    #define Read()  freopen("data.in", "r", stdin)
    #define Write() freopen("data.out", "w", stdout);
    
    typedef long long LL;
    const double eps = 1e-6;
    const double PI = acos(-1.0);
    const int inf = ~0u>>2;
    
    using namespace std;
    
    const int N = 50010;
    
    int dbcmp(double x) {
        if(x < -eps)    return -1;
        else if(x > eps)    return 1;
        else    return 0;
    }
    
    struct point {
        double x;
        double y;
        bool operator < (const point b) const {
            if(dbcmp(y - b.y) == 0) return dbcmp(x - b.x) < 0;
            return dbcmp(y - b.y) < 0;
        }
    }p[N], pol[N];
    
    int st[N], n, m, t;
    bool vis[N];
    
    double det(double x1, double y1, double x2, double y2) {
        return x1*y2 - x2*y1;
    }
    
    double cross(point a, point b, point c) {
        return det(b.x - a.x, b.y - a.y, c.x - a.x, c.y - a.y);
    }
    
    double dis2(point a, point b) {
        return (b.x - a.x)*(b.x - a.x) + (b.y - a.y)*(b.y - a.y);
    }
    
    void Graham(int dir) {
        int i;
        t = 0;
        for(i = 0; i < n; ++i) {
            if(vis[i])  continue;
            while(t > 1 && cross(p[st[t-1]], p[st[t]], p[i])*dir <= 0)   --t;
            st[++t] = i;
        }
        for(i = 2; i < t; ++i)  vis[st[i]] = true;
    }
    
    void get_convex_polygons() {
        int i;
        sort(p, p + n);
        CL(vis, false);
        Graham(1);
        m = 0;
        for(i = 1; i <= t; ++i) pol[m++] = p[st[i]];
        Graham(-1);
        for(i = 1; i < t; ++i)  pol[m++] = p[st[t-i]];
    }
    
    double roating_calipers() {
        int i, q = 1;
        double ans = 0;
        for(i = 0; i < m - 1; ++i) {
            while(cross(pol[i + 1], pol[q+1], pol[i]) > cross(pol[i + 1], pol[q], pol[i])) {
                q = (q + 1)%m;
            }
            ans = max(ans, max(dis2(pol[i], pol[q]), dis2(pol[i+1], pol[q])));
        }
        return ans;
    }
    
    int main() {
        //freopen("data.in", "r", stdin);
    
        while(~scanf("%d", &n)) {
            for(int i = 0; i < n; ++i) {
                scanf("%lf%lf", &p[i].x, &p[i].y);
            }
            get_convex_polygons();
            printf("%.0f\n", roating_calipers());
        }
        return 0;
    }

    POJ 2079

    用类似选择卡壳的思想。题目让求最大的三角形面积。开始的时候理解成三角形上必须有一个边在凸包上了。O(n^2)枚举边,然后用旋转卡壳的思想确定第3个点。

    View Code
    //#pragma comment(linker,"/STACK:327680000,327680000")
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <set>
    #include <functional>
    #include <numeric>
    #include <sstream>
    #include <stack>
    #include <map>
    #include <queue>
    
    #define CL(arr, val)    memset(arr, val, sizeof(arr))
    #define REP(i, n)       for((i) = 0; (i) < (n); ++(i))
    #define FOR(i, l, h)    for((i) = (l); (i) <= (h); ++(i))
    #define FORD(i, h, l)   for((i) = (h); (i) >= (l); --(i))
    #define L(x)    (x) << 1
    #define R(x)    (x) << 1 | 1
    #define MID(l, r)   (l + r) >> 1
    #define Min(x, y)   (x) < (y) ? (x) : (y)
    #define Max(x, y)   (x) < (y) ? (y) : (x)
    #define E(x)        (1 << (x))
    #define iabs(x)     (x) < 0 ? -(x) : (x)
    #define OUT(x)  printf("%I64d\n", x)
    #define Read()  freopen("data.in", "r", stdin)
    #define Write() freopen("data.out", "w", stdout);
    
    typedef long long LL;
    const double eps = 1e-6;
    const double PI = acos(-1.0);
    const int inf = ~0u>>2;
    
    using namespace std;
    
    const int N = 50010;
    
    int dbcmp(double x) {
        if(x < -eps)    return -1;
        else if(x > eps)    return 1;
        else    return 0;
    }
    
    struct point {
        double x;
        double y;
        bool operator < (const point b) const {
            if(dbcmp(y - b.y) == 0) return dbcmp(x - b.x) < 0;
            return dbcmp(y - b.y) < 0;
        }
    }p[N], pol[N];
    
    int st[N], n, m, t;
    bool vis[N];
    
    double det(double x1, double y1, double x2, double y2) {
        return x1*y2 - x2*y1;
    }
    
    double cross(point a, point b, point c) {
        return det(b.x - a.x, b.y - a.y, c.x - a.x, c.y - a.y);
    }
    
    double dis2(point a, point b) {
        return (b.x - a.x)*(b.x - a.x) + (b.y - a.y)*(b.y - a.y);
    }
    
    void Graham(int dir) {
        int i;
        t = 0;
        for(i = 0; i < n; ++i) {
            if(vis[i])  continue;
            while(t > 1 && cross(p[st[t-1]], p[st[t]], p[i])*dir <= 0)   --t;
            st[++t] = i;
        }
        for(i = 2; i < t; ++i)  vis[st[i]] = true;
    }
    
    void get_convex_polygons() {
        int i;
        sort(p, p + n);
        CL(vis, false);
        Graham(1);
        m = 0;
        for(i = 1; i <= t; ++i) pol[m++] = p[st[i]];
        Graham(-1);
        for(i = 1; i < t; ++i)  pol[m++] = p[st[t-i]];
        /*
        for(i = 0; i < m; ++i) {
            printf("%.0f %.0f\n", pol[i].x, pol[i].y);
        }
        */
    }
    
    double roating_calipers() {
        int i, j, q = 1;
        double ans = 0;
        for(i = 0; i < m - 1; ++i) {
            q = 1;
            for(j = i + 1; j < m; ++j) {
                while(cross(pol[j], pol[q+1], pol[i]) > cross(pol[j], pol[q], pol[i])) {
                    q = (q + 1)%(m - 1);
                }
                ans = max(ans, fabs(cross(pol[q], pol[i], pol[j])));
            }
        }
        return ans;
    }
    
    int main() {
        //freopen("data.in", "r", stdin);
    
        while(~scanf("%d", &n)) {
            if(n == -1) break;
            for(int i = 0; i < n; ++i) {
                scanf("%lf%lf", &p[i].x, &p[i].y);
            }
            get_convex_polygons();
            printf("%.2f\n", roating_calipers()/2);
        }
        return 0;
    }
  • 相关阅读:
    百度多图上传
    uploadify--上传文件控件
    JS获取时间
    CSS选择器
    派大星博客的美化之路
    百度地图--JS版
    css实现元素下出现横线动画
    盒模型显隐、定位与流式布局思想
    css进度条
    Build Sharepoint 2013 Farm
  • 原文地址:https://www.cnblogs.com/vongang/p/2921755.html
Copyright © 2020-2023  润新知