图~

来源:互联网 发布:ps软件安装教程 编辑:程序博客网 时间:2024/04/29 13:22
凸包:凸包游戏:N个点中去掉一个得到N个点集,求这些点集构成的凸包的最小面积?(除了POINT类,其他看挑战书)不难想到去掉的点一定是凸包的顶点,于是就可以2000MS+水过去:#include <iostream>#include <vector>#include <algorithm>#include <cmath>using namespace std;#define MAX_N 100000 + 16typedef int type_xy;typedef struct Point{    int id;    type_xy x, y;    Point() {}    Point(type_xy x, type_xy y) : x(x), y(y) {}    Point operator + (Point p){ return Point(x + p.x, y + p.y); }    Point operator - (const Point& p){ return Point(x - p.x, y - p.y); }    Point operator * (type_xy d){ return Point(x*d, y*d); }    bool operator < (const Point& a) const    {        if (x != a.x) return x < a.x;        else return y < a.y;    }    type_xy dot(Point p) { return x*p.x + y*p.y; }    type_xy det(Point p) { return x*p.y - y*p.x; }};Point P[MAX_N], Q[MAX_N];// 向量AB 与 AC 的叉积 如果叉积大于0,那么C在向量AB的逆时针方向,叉积小于0则在AB的顺时针方向。如果叉积等于0,则ABC共线。inline type_xy cross(Point A, Point B, Point C){    return (B - A).det(C - A);}// AB和AC构成的平行四边形面积inline type_xy compute_area(Point A, Point B, Point C){    type_xy res = cross(A, B, C);    if (res < 0)    {        return -res;    }    return res;}// 求多边形面积inline type_xy compute_area(const vector<Point>& ps){    type_xy total = 0;    for (int i = 2; i < ps.size(); ++i)    {        total += compute_area(ps[0], ps[i - 1], ps[i]);    }    return total;}// 求凸包vector <Point> convex_hull(Point *ps, int N){    sort(ps, ps + N);    int k = 0;   // 凸包的顶点数    vector <Point> qs(N * 2);   // 构造中的凸包    // 构造凸包的下侧    for (int i = 0; i < N; ++i)    {        while (k > 1 && (qs[k - 1] - qs[k - 2]).det(ps[i] - qs[k - 1]) <= 0) --k;        qs[k++] = ps[i];    }    // 构造凸包的上侧    for (int i = N - 2, t = k; i >= 0; --i)    {        while (k > t && (qs[k - 1] - qs[k - 2]).det(ps[i] - qs[k - 1]) <= 0) --k;        qs[k++] = ps[i];    }    qs.resize(k - 1);    return qs;}///////////////////////////SubMain//////////////////////////////////int main(int argc, char *argv[]){#ifndef ONLINE_JUDGE    freopen("in.txt", "r", stdin);    freopen("out.txt", "w", stdout);#endif    int N;    while (~scanf("%d", &N) && N > 0)    {        for (int i = 0; i < N; ++i)        {            scanf("%d%d", &P[i].x, &P[i].y);            P[i].id = i;        }        memcpy(Q, P, N * sizeof(Point));        vector<Point> ps = convex_hull(P, N);        type_xy ans = 0x3f3f3f3f;        for (int i = 0; i < ps.size(); ++i)        {            memcpy(P, Q, N * sizeof(Point));            swap(P[ps[i].id], P[N - 1]);            ans = min(ans, compute_area(convex_hull(P, N - 1)));        }        printf("%d.%s\n", ans / 2, ans % 2 == 1 ? "50" : "00");    }#ifndef ONLINE_JUDGE    fclose(stdin);    fclose(stdout);    system("out.txt");#endif    return 0;}
0 0
原创粉丝点击