您的位置:首页 > 其它

入住CSDN的第一篇文章,纪念我的第一道凸包题

2011-03-18 23:40 211 查看
题目:Feeding Girls

题目描述

Blair是一个视女人如命的人,都说狡兔三窟,所以Blair也有不止一条命(不止一个女人)。但是坐在Blair旁边的可是^<B_G>^_DrEaM,这个对女人垂涎三尺的男人整天盘算着怎么把Blair的女人一个个掀翻><。每天中午跑饭时是最危险的时候,因为Blair没法同时陪所有女人吃饭。Blair能力有限,每天照顾不好每个女人,时间长了女人跑饭时因为Blair没能力而跟^<B_G>^_DrEaM跑掉,Blair为了不让女人跟^<B_G>^_DrEaM跑掉,想要建造一个围栏用来围住他的女人,可是他资金匮乏。他建造的围栏必须包括他的女人喜欢吃饭的所有地点。对于给出的这些地点的坐标,计算最短的能够围住这些女人的围栏的长度。

输入格式

输入数据的第一行包括一个整数 N。N(0 <= N <= 10,000)表示Blair想要围住的女人的数目。接下来 N 行,每行由两个实数组成,Xi 和 Yi,对应平面上的女人吃饭点的坐标(-1,000,000 <= Xi,Yi <= 1,000,000)。数字用小数表示。

输出格式

输出必须包括一个实数,表示必须的围栏的长度。答案保留两位小数。

样例输入

4
4 8
4 12
5 9.3
7 8

样例输出

12.00

第一道凸包题,也是计算几何的第二道。用Graham扫描法,通过叉积判断方向。

速度在FP中排第十,但是写起来并不是一帆风顺,囧。。。

题目:Feeding Girls

状态:Accepted
测评机:Xeost[5]
得分:100分
提交日期:2011-3-18 23:24:00
有效耗时:1531毫秒
测试结果1:通过本测试点|有效耗时156ms
测试结果2:通过本测试点|有效耗时156ms
测试结果3:通过本测试点|有效耗时156ms
测试结果4:通过本测试点|有效耗时157ms
测试结果5:通过本测试点|有效耗时171ms
测试结果6:通过本测试点|有效耗时188ms
测试结果7:通过本测试点|有效耗时203ms
测试结果8:通过本测试点|有效耗时250ms
测试结果9:通过本测试点|有效耗时47ms
测试结果10:通过本测试点|有效耗时47ms
提交代码:
Program ConvexHull_FeedingGrils;
Type point=record
x,y:real;
end;
Var s:array[0..100000] of point;
c:array[0..10000] of point;
p:point;
i,j,k,m,n,t:longint;
len:real;
Function Calc(p1,p2,p0:point):real;
begin
calc:=(p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
end;
Function Dist(p1,p0:point):real;
begin
dist:=sqrt(sqr(p1.x-p0.x)+sqr(p1.y-p0.y));
end;
Procedure Qsort(t,s:longint);
var i,j:longint;
p,mid:point;
begin
i:=t;j:=s;mid:=c[(i+j) shr 1];
repeat
while (calc(c[i],mid,c[0])>0)or(calc(c[i],mid,c[0])=0)
and(dist(c[i],c[0])<dist(mid,c[0])) do inc(i);
while (calc(c[j],mid,c[0])<0)or(calc(c[j],mid,c[0])=0)
and(dist(c[j],c[0])<dist(mid,c[0])) do dec(j);
if i<=j then
begin
p:=c[i];
c[i]:=c[j];
c[j]:=p;
inc(i);dec(j);
end;
until i>j;
if i<s then Qsort(i,s);
if t<j then Qsort(t,j);
end;
Begin
readln(n);
c[0].x:=maxlongint;c[0].y:=maxlongint;
for i:=0 to n-1 do
begin
readln(c[i].x,c[i].y);
if (c[i].y<c[0].y) or (c[i].y=c[0].y) and (c[i].x<c[0].x) then
begin
p:=c[0];
c[0]:=c[i];
c[i]:=p;
end;
end;
if n>2 then
Qsort(1,n-1);
for i:=1 to 3 do
begin
if (c[i].x=0 )and(c[i].y=0) then break; //要加这一句,否则会WA一个点 106错误
s[i]:=c[i-1];
t:=i;
end;
for i:=3 to n-1 do
begin
while (t<>0)and(calc(s[t],c[i],s[t-1])<=0) do
dec(t);
inc(t);
s[t]:=c[i];
end;
len:=0;
for i:=2 to t do
len:=len+dist(s[i],s[i-1]);
if t<>0 then
len:=len+dist(s[t],s[1]);
writeln(len:0:2);
End.


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: