Title
http://poj.org/problem?id=3348
Solution
改了很久的原因竟然因为忘记了取绝对值(因为之前洛谷的求多边形面积的模板不取绝对值也可以过)
-
J a r i v s Jarivs Jarivs时间复杂度要 O ( n m ) O(nm) O(nm)
-
#Jarivs算法# [luogu P2742] [USACO5.1]圈奶牛Fencing the Cows /【模板】二维凸包
-
G r a h a m Graham Graham优秀一些,时间复杂度要 O ( n l o g 2 n ) O(nlog_{2}n) O(nlog2n),主要是快速排序的时间
-
主要步骤:
- 取y值最小的且最左的点,对剩下的点关于这个点的极角排序(极角一样取最远的点)
- 顺时针进凸包处理,处理时发现当前处理的
P
i
\boldsymbol{P_i}
Pi,
V
j
−
1
V
j
→
\boldsymbol{ \overrightarrow{V_{j-1}Vj}}
Vj−1Vj到
V
j
P
i
→
\boldsymbol{\overrightarrow{V_jP_i}}
VjPi为逆时针或
0
0
0角度旋转时,
V
j
−
1
,
V
j
,
P
i
V_{j-1},Vj,Pi
Vj−1,Vj,Pi呈凹形,
V
j
Vj
Vj一定不是凸包的顶点,退出
V
V
V序列(
V
V
V
序列指的是凸包顶点序列
)
下面是两项失败品:
//迷之wa?
P[sta[top]]=P[1];
double ans=0;
for(int i=1;i<top;i++) ans+=(P[sta[i]]*P[sta[i+1]]);
printf("%lld",(long long)(ans/100.0));
return 0;
//求周长
top--;
double ans=sqrt(dist2(P[sta[top]],P[sta[1]]));
for(int i=2;i<=top;i++)
ans+=sqrt(dist2(P[sta[i]],P[sta[i-1]]));
printf("%.2lf",ans);
return 0; */
Code
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=10005;
const double eps=1e-10;
double x[110],y[110],ans=0;
struct point{
double x,y;
point operator - (point&s)
{return (point){x-s.x,y-s.y};}
}P[maxn];
double operator *(point a,point b){
return a.x*b.y-b.x*a.y;
}
int n,sta[maxn],top;
inline double dist2(point P1,point P2){
return (P1.x-P2.x)*(P1.x-P2.x)+(P1.y-P2.y)*(P1.y-P2.y);
}
inline bool judgeOnLeft(point p0,point p1,point p2){
double s=(p1-p0)*(p2-p0);
return s<0||(s==0&&dist2(p1,p0)>=dist2(p2,p0));
}
inline bool cmp(point p1,point p2){
double s=(p1-P[1])*(p2-P[1]);
return s<0||(s==0&&dist2(p1,P[0])>=dist2(p2,P[0]));
}
int main(){
scanf("%d",&n);
int First=1;
for(int i=1;i<=n;i++) {
scanf("%lf%lf",&P[i].x,&P[i].y);
if (P[i].x<P[First].x||(P[i].x==P[First].x&&P[i].y<P[First].y)) First=i;
}
swap(P[First],P[1]);
sort(&P[2],&P[n+1],cmp);
P[n+1]=P[1];
sta[1]=1; sta[2]=2;
top=2;
for(int i=3;i<=n+1;i++){
while(top>1&&judgeOnLeft(P[sta[top-1]],P[i],P[sta[top]])) top--;
sta[++top]=i;
}
top--;
for(int i=1;i<top;i++) ans+=abs(P[sta[i]]*P[sta[i+1]])/2.0;
ans+=abs(P[sta[top]]*P[sta[1]])/2.0;
printf("%lld",(long long)ans/50);
}