您的位置:首页 > 其它

POJ 3246:Game 题解 (凸包)

2017-08-12 15:21 435 查看
题目链接:http://poj.org/problem?id=3246

题目大意:给你N个点,首先求出这N个点构成的凸包,然后对凸包中的每个点,求除去这个点后剩下N-1个点重新构成的凸包的最小面积。

代码测试情况:AC Memory:1804K Time:297ms

解题分析:将点集按照x->y的顺序排序,然后构造一个函数求点集中一定下标范围内的点的上半个或下半个凸包。首先求出整个凸包及面积S,然后对于凸包上的每个点x1,对其在凸包上相邻的两个点(x2,x3)的在点集中的下标范围中的点求上半或下半凸包面积S’(此时忽略该中间点),然后新的凸包面积Snew=S-(x2-x1)×(x3-x1)+S’。除去排序外复杂度为O(N)。另外对凸包S中的左下点和右上点要单独计算凸包。

#include<cstdio>
#include<vector>
#include<algorithm>
#include<cmath>
#include<string.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
#define fi first
#define se second
#define vec vector
const double eps=1e-6;
const int inf=0x3f3f3f3f;
#define N int(1e5+5)

vec<P> a;
int n;
double cp(int x1,int x2,int x3,int x4){//cross product
P c=P(a[x2].fi-a[x1].fi,a[x2].se-a[x1].se);
P b=P(a[x4].fi-a[x3].fi,a[x4].se-a[x3].se);
return b.fi*c.se-b.se*c.fi;
}

double build(int from,int to,int v,vec<int> &c){
c.push_back(to);
c.push_back(from);
int di=from<to?1:-1;
for (int i = from+1; i != to+di; i+=di){
if(i==v)continue;
while(c.back()!=from && cp(c[c.size()-2],c.back(),c.back(),i)<=0)c.pop_back();
c.push_back(i);
}
if(c.size()==3)return 0;
double ret=0;
for (int i = 2; i < c.size()-1; i++){
ret+=cp(c[1],c[i],c[1],c[i+1])/2;
}
return ret;
}

vec<int> up,down,t1,t2;
void solve(){
sort(a.begin(),a.end());
double s=build(0,a.size()-1,-1,up)+build(a.size()-1,0,-1,down);
double s1=build(0,a.size()-2,-1,t1)+build(a.size()-2,0,-1,t2);
t1.clear();t2.clear();
s1=min(s1,build(1,a.size()-1,-1,t1)+build(a.size()-1,1,-1,t2));
for(int i=2;i<up.size()-1;i++){
t1.clear();
s1=min(s1,s+build(up[i-1],up[i+1],up[i],t1)-cp(up[i-1],up[i],up[i-1],up[i+1])/2);
}
for (int i = 2; i < down.size()-1; i++){
t1.clear();
s1=min(s1,s+build(down[i-1],down[i+1],down[i],t1)-cp(down[i-1],down[i],down[i-1],down[i+1])/2);
}
printf("%.2f\n",s1);
}

int main(){
while(scanf("%d",&n),n){
up.clear();down=t1=t2=up;a.clear();
for (int i = 0; i < n; i++){
int x,y;
scanf("%d %d",&x,&y);
a.push_back({x,y});
}
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj