zoukankan      html  css  js  c++  java
  • POJ 1696 (凸包变形 || 极角排序)

    题目: 传送门

    题意: 给你 n 个点, 然后, 有一只蚂蚁, 问你蚂蚁只能直走和左转,问蚂蚁要怎么走才能走最多的点。

    题解: 其实就是求很多个凸包, 蚂蚁肯定能走完所有点。

        或者可以极角排序,先选左下角为基准点排序,然后之后更新基准点不断排序即可。

    /// 凸包
    #include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #include <queue> #include <map> #include <vector> #include <set> #include <string> #include <math.h> #define LL long long #define mem(i, j) memset(i, j, sizeof(i)) #define rep(i, j, k) for(int i = j; i <= k; i++) #define dep(i, j, k) for(int i = k; i >= j; i--) #define pb push_back #define make make_pair #define INF INT_MAX #define inf LLONG_MAX #define PI acos(-1) using namespace std; const int N = 5e4 + 5; struct Point { int id; double x, y; Point(double x = 0, double y = 0) : x(x), y(y) { } /// 构造函数 }; typedef Point Vector; /// 向量+向量=向量, 点+向量=向量 Vector operator + (Vector A, Vector B) { return Vector(A.x + B.x, A.y + B.y); } ///点-点=向量 Vector operator - (Point A, Point B) { return Vector(A.x - B.x, A.y - B.y); } ///向量*数=向量 Vector operator * (Vector A, double p) { return Vector(A.x * p, A.y * p); } ///向量/数=向量 Vector operator / (Vector A, double p) { return Vector(A.x / p, A.y / p); } const double eps = 1e-10; int dcmp(double x) { if(fabs(x) < eps) return 0; else return x < 0 ? -1 : 1; } bool operator < (const Point& a, const Point& b) { return a.x == b.x ? a.y < b.y : a.x < b.x; } bool operator == (const Point& a, const Point &b) { return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0; } double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; } /// 点积 double Length(Vector A) { return sqrt(Dot(A, A)); } /// 计算向量长度 double Angle(Vector A, Vector B) { return acos(Dot(A, B) / Length(A) / Length(B)); } /// 向量A、B夹角 double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; } /// 叉积 Point P[N], ans[N]; bool vis[N]; void ConvexHull(int st, int n) { mem(vis, 0); int k = 0, t = 1; while(k < n) { rep(i, st, n - 1) { if(vis[P[i].id]) continue; while(k > t && Cross(ans[k - 1] - ans[k - 2], P[i] - ans[k - 1]) <= 0) k--, vis[ans[k].id] = 0; ans[k++] = P[i]; vis[P[i].id] = 1; } t = k; dep(i, 0, n - 2) { if(vis[P[i].id]) continue; while(k > t && Cross(ans[k - 1] - ans[k - 2], P[i] - ans[k - 1]) <= 0) k--, vis[ans[k].id] = 0; ans[k++] = P[i]; vis[P[i].id] = 1; } t = k; st = 0; } } void solve() { int n; scanf("%d", &n); double mi = 150.0, pos = -1; rep(i, 0, n - 1) { scanf("%d %lf %lf", &P[i].id, &P[i].x, &P[i].y); } sort(P, P + n); rep(i, 0, n - 1) if(P[i].y < mi) mi = P[i].y, pos = i; ConvexHull(pos, n); printf("%d ", n); rep(i, 0, n - 1) printf("%d ", ans[i].id); puts(""); } int main() { int _; scanf("%d", &_); while(_--) solve(); return 0; }
    /// 极角排序
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <queue>
    #include <map>
    #include <vector>
    #include <set>
    #include <string>
    #include <math.h>
    #define LL long long
    #define mem(i, j) memset(i, j, sizeof(i))
    #define rep(i, j, k) for(int i = j; i <= k; i++)
    #define dep(i, j, k) for(int i = k; i >= j; i--)
    #define pb push_back
    #define make make_pair
    #define INF INT_MAX
    #define inf LLONG_MAX
    #define PI acos(-1)
    using namespace std;
    
    const int N = 1e2 + 5;
    const double eps = 1e-10;
    
    struct Point {
        int id;
        double x, y;
        Point(double x = 0, double y = 0) : x(x), y(y) { }
    };
    
    int dcmp(double x) {
        if(fabs(x) < eps) return 0; else return x > 0 ? 1 : -1;
    }
    
    Point operator + (Point A, Point B) { return Point(A.x + B.x, A.y + B.y); }
    Point operator - (Point A, Point B) { return Point(A.x - B.x, A.y - B.y); }
    Point operator * (Point A, double p) { return Point(A.x * p, A.y * p); }
    Point operator / (Point A, double p) { return Point(A.x / p, A.y / p); }
    
    double Cross(Point A, Point B) { return A.x * B.y - A.y * B.x; }
    double Dot(Point A, Point B) { return A.x * B.x + A.y * B.y; }
    double Length(Point A) { return sqrt(Dot(A, A)); }
    
    Point P[N];
    int cnt;
    
    bool cmp(Point A, Point B) {
        double tmp = Cross(A - P[cnt], B - P[cnt]);
        if(dcmp(tmp) == 0) return Length(A - P[cnt]) < Length(B - P[cnt]);
        return dcmp(tmp) >= 0;
    }
    
    void solve() {
        int n; scanf("%d", &n);
        rep(i, 0, n - 1) {
            scanf("%d %lf %lf", &P[i].id, &P[i].x, &P[i].y);
            if(P[i].y < P[0].y || (P[i].y == P[0].y && P[i].x < P[0].x)) swap(P[i], P[0]);
        }
        cnt = 0;
        rep(i, 1, n - 1) {
            sort(P + i, P + n, cmp);
            cnt++;
        }
        printf("%d", n);
        rep(i, 0, n - 1) printf(" %d", P[i].id); puts("");
    }
    
    int main() {
        int _; scanf("%d", &_);
        while(_--) solve();
        return 0;
    }
    一步一步,永不停息
  • 相关阅读:
    LeetCode15 3Sum
    LeetCode10 Regular Expression Matching
    LeetCode20 Valid Parentheses
    LeetCode21 Merge Two Sorted Lists
    LeetCode13 Roman to Integer
    LeetCode12 Integer to Roman
    LeetCode11 Container With Most Water
    LeetCode19 Remove Nth Node From End of List
    LeetCode14 Longest Common Prefix
    LeetCode9 Palindrome Number
  • 原文地址:https://www.cnblogs.com/Willems/p/12346573.html
Copyright © 2011-2022 走看看