# [BZOJ 3707] 圈地

BZOJ 3707 传送门

## Code:

#include <bits/stdc++.h>

using namespace std;
#define X first
#define Y second
#define pb push_back
typedef double db;
typedef pair<db,db> P;
typedef long long ll;
const int MAXN=1e3+10;
db res=1e60,INF=1e60;P dat[MAXN];
int n,seq[MAXN],mp[MAXN],tot;

P operator - (P a,P b)
{return P(a.X-b.X,a.Y-b.Y);}
inline db Cross(P a,P b)
{return a.X*b.Y-a.Y*b.X;}
inline db Slope(P a,P b)
{return a.X!=b.X?(a.Y-b.Y)/(a.X-b.X):INF;}
struct Line{double x,y,slope;}line[MAXN*MAXN];
bool cmp(Line a,Line b){return a.slope<b.slope;}
inline db solve(int a,int b,int c)
{return fabs(Cross(dat[b]-dat[a],dat[c]-dat[a]))/2.0;}

int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lf%lf",&dat[i].X,&dat[i].Y);
sort(dat+1,dat+n+1);
for(int i=1;i<=n;i++)
seq[i]=mp[i]=i;
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
//注意与y轴平行的线要放在最后处理(数据的锅？)
line[++tot]=(Line){i,j,Slope(dat[i],dat[j])};
sort(line+1,line+tot+1,cmp);
//将y轴不断旋转并维护当前从左向右的序列
for(int i=1;i<=tot;i++)
{
int a=line[i].x,b=line[i].y;
if(seq[a]>seq[b]) swap(a,b);
if(seq[a]>1) res=min(res,solve(a,b,mp[seq[a]-1]));
if(seq[b]<n) res=min(res,solve(a,b,mp[seq[b]+1]));
swap(seq[a],seq[b]);
swap(mp[seq[a]],mp[seq[b]]);
}
printf("%.2lf",res);
return 0;
}

posted @ 2018-09-28 13:25  NewErA  阅读(169)  评论(0编辑  收藏  举报