poj2079 Triangle

Link

Notice

如果谁能证明\(O(N)\)算法的正确性,请给本蒟蒻指点一下。。 # Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//Code by Lucida
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define red(x) scanf("%d",&x)
#define fred(x) scanf("%lf",&x)
template <class T> inline bool chkmx(T &a,const T &b){return a<b?a=b,1:0;}
template <class T> inline bool chkmn(T &a,const T &b){return a>b?a=b,1:0;}
const int MAXN=50000+10;
using std::swap;
using std::sort;
typedef double ld;
const ld eps=1e-7,pi=acos(-1.0);
int fcmp(ld x)
{
if(-eps<x && x<eps) return 0;
return x<0?-1:1;
}
template <class T> T sqr(T x){return x*x;}
template <class T> T abs(T x){return x>0?x:-x;}
struct vec
{
ld x,y;
vec(ld _x=0,ld _y=0):x(_x),y(_y){}
vec operator -(){return vec(-x,-y);}
ld norm(){return sqrt(x*x+y*y);}
void operator +=(vec a){x+=a.x,y+=a.y;}
void operator -=(vec a){x-=a.x,y-=a.y;}
void operator /=(ld a){x/=a,y/=a;}
void operator *=(ld a){x*=a,y*=a;}
bool operator ==(vec a){return x==a.x && y==a.y;}
};
typedef vec point;
vec operator +(vec a,vec b){return vec(a.x+b.x,a.y+b.y);}
vec operator -(vec a,vec b){return vec(a.x-b.x,a.y-b.y);}
vec operator *(vec a,ld t){return vec(a.x*t,a.y*t);}
vec operator /(vec a,ld t){return vec(a.x/t,a.y/t);}
ld inner(vec a,vec b){return a.x*b.x+a.y*b.y;}
ld outer(vec a,vec b){return a.x*b.y-a.y*b.x;}
struct line
{
point a;vec v;
line(point _a,vec _v):a(_a),v(_v){}
};
bool cmp(const point &a,const point &b)
{
if(fcmp(outer(a,b))!=0)
return fcmp(outer(a,b))>0;
return inner(a,a)<inner(b,b);
}
void Graham(point *p,int &n)
{
int mi=1;
for(int i=1;i<=n;i++)
if(p[mi].x<p[i].x || (p[mi].x==p[i].x && p[mi].y<p[i].y)) mi=i;
swap(p[mi],p[1]);p[0]=p[1];
for(int i=1;i<=n;i++) p[i]-=p[0];
sort(p+2,p+1+n,cmp);
for(int i=1;i<=n;i++) p[i]+=p[0];
static point Sp[MAXN];
int top=0;
p[n+1]=p[1];
for(int i=1;i<=n+1;i++)
{
while(top>=2 && fcmp(outer(p[i]-Sp[top],Sp[top]-Sp[top-1]))>=0) top--;
Sp[++top]=p[i];
}
top--;
for(int i=1;i<=top;i++) p[i]=Sp[i];
n=top;
}
ld dist(point a,line l){return abs(outer(a-l.a,l.v))/l.v.norm();}
void WORK(int n)
{
static point p[MAXN];
for(int i=1;i<=n;i++)
fred(p[i].x),fred(p[i].y);
Graham(p,n);
ld ANS=-1;
#define suc(x) (x+1>n?1:x+1)
for(int i=1;i<=n;i++)
for(int j=suc(i),cur=j;j!=i;j=suc(j))
{
line l=line(p[i],p[j]-p[i]);
while(fcmp(dist(p[suc(cur)],l)-dist(p[cur],l))>0) cur=suc(cur);
chkmx(ANS,l.v.norm()*dist(p[cur],l));
}
#undef suc
printf("%.2f\n",ANS/2);
}
int main()
{
freopen("input","r",stdin);
int n;while(red(n),~n) WORK(n);
return 0;
}

Powered by Hexo and Hexo-theme-hiker

Copyright © 2013 - 2017 Hey,Lucida here. All Rights Reserved.

Lucida Lu 保留所有权利