poj 3246 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\n",sum_max/2,(sum_max&1)?".50":".00"); } return 0; }