poj 3246 Game

Game
Time Limit: 4000MS   Memory Limit: 65536K
Total Submissions: 2707   Accepted: 488

Description

Wintokk likes playing games on convex-hull. One day, Dragon wants to test him.

Dragon has drawn N points on a plane with no points in the same place. Dragon wants to know the smallest of the N convex-hulls formed by removing exactly one point from the N points.

But Wintokk is so stupid. Can you help him find the smallest area after removing a single point?

Input

The input contains several test cases.

Each test starts with an integer N(4 ≤ N < 105+1), the total number of points on the plane.

The next N lines, each contains two integers x and y, indicating the position of the point.

The input ends up with N=0.

Output

Output the smallest area with two digits after the decimal point.

Sample Input

4
1 0
0 0
0 1
1 1
0

Sample Output

0.50

翻译:给定平面上N个点,现在从中去掉一个点,去掉后使得剩余的点所构成的凸包的面积达到最小值,求这个最小值。
思路:直接穷举水过。
AC代码:
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<algorithm>
#include<set>
#include<queue>
#include<cmath>
#include<vector>
#include<bitset>
#include<string>
#include<queue>
#include<cstring>
#include<cstdio>
#include <climits>
using namespace std;
#define INF 0x3f3f3f3f
const int N_MAX = 100000 + 5;
int N;
struct P {
    int x, y,id;
    P() {}
    P(int x, int y) :x(x),y(y){}
    P operator +(P p) {
        return P(x + p.x, y + p.y);
    }
    P operator -(P p) {
        return P(x - p.x, y - p.y);
    }
    P operator *(int d) {
        return P(x*d, y*d);
    }
    int dot(P p) {
        return x*p.x+y*p.y;
    }
    int det(P p) {
        return x*p.y - y*p.x;
    }
    int norm() {
        return x*x + y*y;
    }
    bool operator < (const P& b)const{
        if (x != b.x)return x < b.x;
        return y < b.y;
    }
    
};
P p[N_MAX],tmp[N_MAX];
struct Segment{
    P p1, p2;
    Segment(P p1,P p2):p1(p1),p2(p2) {}
};
typedef Segment Line;

int GetArea(Segment l ,P p) {//计算直线l和点P所构成的平行四边形面积
    return abs((l.p2 - l.p1).det(p - l.p1));
}

vector<P>convex_hull(P*ps, int n) {
    sort(ps, ps + n);
    int k = 0;
    vector<P>qs(2 * n);
    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;
}
typedef vector<P> Polygon;

int GetArea_convexhull(Polygon ps) {//计算凸多边形面积
    int sum = 0;
    
    for (int i = 2; i < ps.size();i++) {
        P p1 = ps[i], p2 = ps[i-1];
    Segment l = Segment(p1, p2);
        sum += GetArea(l, ps[0]);
    }
    return sum;
}

int main() {
    while (scanf("%d",&N)&&N) {
        for (int i = 0; i < N;i++) {
            scanf("%d%d",&p[i].x,&p[i].y);
            p[i].id = i;
        }
        memcpy(tmp, p, sizeof(p));
        int sum_max = INT_MAX;
        Polygon ps = convex_hull(p, N);//要去除的点一定在凸包上
        for (int i = 0; i < ps.size();i++) {
            memcpy(p, tmp, sizeof(tmp));
            swap(p[ps[i].id], p[N - 1]);//将第i个凸包上的点去除
            int sum=GetArea_convexhull(convex_hull(p, N - 1));
            sum_max =min(sum_max, sum);
        }
        printf("%d%s
",sum_max/2,(sum_max&1)?".50":".00");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/ZefengYao/p/7612464.html