Vijos P1253
@.@多边形面积
描述 Description
在直角坐标系中,给出n个顶点的坐标,求这n个点所围成的图形的周长和面积。
注意:
(1)如果所有点共线则周长按直线的长度计算,面积视为0;
(2)如果部分点共线按共线后的多边形计算;
(3)所给出的n个顶点如果能围成多边形均为突多边形。
输入格式 Input Format
第一行输入多边形顶点个数n(3<=n<=10);
接下来n行每行输入一个顶点坐标x,y,x,y均为整数且坐标的绝对值均不超过10。
输出格式 Output Format
两行,即多边形的周长和面积(均保留两位小数)。
样例输入 Sample Input
4 0 0 1 0 0 1 1 1
样例输出 Sample Output
4.00 1.00
时间限制 Time Limitation
各个测试点1s
注释 Hint
来源 Source
Alphonse.Elric
program p1233;
uses math;
Var
a,b:array[0..20] of real;
n,i,j,now,mini,maxi,top1,top2:longint;
v,d:array[0..20] of boolean;
q1,q2,pre:array[0..20] of longint;
mincos,maxcos,sum,maxdt:real;
Procedure fopen;
begin
assign(input,'p1233.in');
assign(output,'p1233.out');
reset(input);
rewrite(output);
end;
Procedure fclose;
begin
close(input);
close(output);
end;
Function Cos(x,y:real):real;
begin
exit(x/sqrt(x*x+y*y));
end;
Procedure swap(var a,b:real);
var
y:real;
begin
y:=a;
a:=b;
b:=y;
end;
Function dt(x1,y1,x2,y2:real):real;
begin
exit(sqrt( sqr(x1-x2)+ sqr(y1-y2)));
end;
Function size(x1,y1,x2,y2:real):real;
begin
exit((x1*y2-x2*y1)/2);
end;
Function inline(x,y,x1,y1,x2,y2:real):boolean;
begin
if (x2=x1) then
if (x=x1) and (y<max(y1,y2)) and (y>min(y1,y2)) then exit(true) else
exit(false);
if ((x=x1) or (x=x2)) then exit(false);
if ((y-y1)/(x-x1)=(y-y2)/(x-x2)) and (y<max(y1,y2)) and (y>min(y1,y2)) then exit(true) else
exit(false);
end;
begin
//a=(1,0) b=(x,y)
//cos<a,b> a在b的右侧 =x/|b|
fopen;
readln(n);
for i:=1 to n do
begin
readln(a[i],b[i]);
writeln(stderr,a[i],' ',b[i]);
end;
for i:=1 to n do
for j:=i+1 to n do
if (b[i]>b[j]) or ((b[i]=b[j]) and (a[i]>a[j])) then
begin
swap(a[i],a[j]);
swap(b[i],b[j]);
end;
now:=1;
top1:=1;
q1[1]:=1;
fillchar(v,sizeof(v),false);
v[1]:=true;
while now<n do
begin
maxdt:=0;
maxcos:=-maxlongint;
maxi:=0;
for i:=now+1 to n do
if not v[i] and ((cos(a[i]-a[now],b[i]-b[now])>maxcos) or ((cos(a[i]-a[now],b[i]-b[now])=maxcos) and (dt(a[i],b[i],a[now],b[now])>maxdt))) then
begin
maxcos:=cos(a[i]-a[now],b[i]-b[now]);
maxi:=i;
maxdt:=dt(a[i],b[i],a[now],b[now]);
end;
pre[maxi]:=now;
v[maxi]:=true;
inc(top1);
q1[top1]:=maxi;
now:=maxi;
end;
v[1]:=false;
top2:=1;
q2[1]:=n;
now:=n;
while now<>1 do
begin
maxdt:=0;
mincos:=maxlongint;
mini:=0;
for i:=1 to now-1 do
if not v[i] and ((cos(a[i]-a[now],b[i]-b[now])<mincos) or ((cos(a[i]-a[now],b[i]-b[now])=mincos) and (dt(a[i],b[i],a[now],b[now])>maxdt))) then
begin
mincos:=cos(a[i]-a[now],b[i]-b[now]);
mini:=i;
maxdt:=dt(a[i],b[i],a[now],b[now]);
end;
v[mini]:=true;
inc(top2);
q2[top2]:=mini;
now:=mini;
end;
if q2[top2]=0 then dec(top2);
sum:=0;
for i:=1 to top1-1 do
sum:=sum+dt(a[q1[i]],b[q1[i]],a[q1[i+1]],b[q1[i+1]]);
for i:=1 to top2-1 do
if pre[q2[i]]<>q2[i+1] then
sum:=sum+dt(a[q2[i]],b[q2[i]],a[q2[i+1]],b[q2[i+1]]);
writeln(sum:0:2);
sum:=0;
for i:=1 to top1-1 do
sum:=sum+size(a[q1[i]],b[q1[i]],a[q1[i+1]],b[q1[i+1]]);
for i:=1 to top2-1 do
sum:=sum+size(a[q2[i]],b[q2[i]],a[q2[i+1]],b[q2[i+1]]);
writeln(abs(sum):0:2);
fclose;
end.