建设围墙 (wall.pas)题解
建设围墙 (wall.pas)
学校要为一栋教学楼建围墙
为了美观,围墙离楼的距离不能小于一个常数L,求如何建造围墙最节省材料
Input (wall.in)
第一行两个整数N和L,N表示教学楼的顶点个数
接下来N行按顺时针顺序给出教学楼的N个顶点坐标Xi,Yi 用一个空格隔开
顶点不会重合 不会有边在除顶点之外的地方相交,Xi Yi在[-10000,10000]内
Output (wall.out)
输出最小的围墙长度 四舍五入保留整数
Sample
INPUT |
OUTPUT |
9 100 200 400 300 400 300 300 400 300 400 400 500 400 500 200 350 200 200 200 |
1628 |
约定
1 ≤ n ≤ 1000
题解:
这题......就是个凸包嘛!
1 type point=record
2 x,y:real;
3 end;
4 stack=record
5 da:array[0..1000]of point;
6 l:longint;
7 end;
8 var i,n,k,l:longint;p:array[0..1000]of point;r:real;
9 s:stack;t:point;
10 function leep(a,b,c:point):real;
11 begin
12 leep:=(c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x);
13 end;
14 function dis(a,b:point):real;
15 begin
16 dis:=sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));
17 end;
18 procedure qsort(l,r:longint);
19 var i,j:longint;x,t:point;
20 begin
21 i:=l;j:=r;
22 x:=p[(i+j) shr 1];
23 repeat
24 while (leep(p[1],p[i],x)>0)
25 or((leep(p[1],p[i],x)=0)
26 and(dis(p[1],p[i])<dis(p[1],x)))
27 do inc(i);
28 while (leep(p[1],x,p[j])>0)
29 or((leep(p[1],p[j],x)=0)
30 and(dis(p[1],x)<dis(p[1],p[j])))
31 do dec(j);
32 if i<=j then
33 begin
34 t:=p[i];p[i]:=p[j];p[j]:=t;
35 inc(i);dec(j);
36 end;
37 until i>j;
38 if l<j then qsort(l,j);
39 if i<r then qsort(i,r);
40 end;
41 begin
42 assign(input,'wall.in');reset(input);
43 assign(output,'wall.out');rewrite(output);
44 readln(n,l);
45 for i:=1 to n do
46 begin
47 readln(p[i].x,p[i].y);
48 if p[1].y<p[i].y then
49 begin
50 t:=p[1];p[1]:=p[i];p[i]:=t;
51 end;
52 end;
53 qsort(2,n);
54 s.l:=2;
55 s.da[1]:=p[1];s.da[2]:=p[2];
56 for i:=3 to n do
57 begin
58 while (s.l>1)and(leep(s.da[s.l-1],s.da[s.l],p[i])<0) do dec(s.l);
59 inc(s.l);
60 s.da[s.l]:=p[i];
61 end;
62 {while (s.l>1)and(leep(s.da[s.l-1],s.da[s.l],s.da[1])<0) do dec(s.l);
63 k:=1;
64 while (k<s.l-1)and(leep(s.da[s.l],s.da[k],s.da[k+1])<0) do inc(k);
65 r:=0;
66 }
67 for i:=2 to s.l do
68 begin
69 r:=dis(s.da[i],s.da[i-1])+r;
70 end;
71 r:=r+dis(s.da[s.l],s.da[1])+2*pi*l;
72 writeln(r:0:0);
73 close(input);close(output);
74 end.
75
2 x,y:real;
3 end;
4 stack=record
5 da:array[0..1000]of point;
6 l:longint;
7 end;
8 var i,n,k,l:longint;p:array[0..1000]of point;r:real;
9 s:stack;t:point;
10 function leep(a,b,c:point):real;
11 begin
12 leep:=(c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x);
13 end;
14 function dis(a,b:point):real;
15 begin
16 dis:=sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));
17 end;
18 procedure qsort(l,r:longint);
19 var i,j:longint;x,t:point;
20 begin
21 i:=l;j:=r;
22 x:=p[(i+j) shr 1];
23 repeat
24 while (leep(p[1],p[i],x)>0)
25 or((leep(p[1],p[i],x)=0)
26 and(dis(p[1],p[i])<dis(p[1],x)))
27 do inc(i);
28 while (leep(p[1],x,p[j])>0)
29 or((leep(p[1],p[j],x)=0)
30 and(dis(p[1],x)<dis(p[1],p[j])))
31 do dec(j);
32 if i<=j then
33 begin
34 t:=p[i];p[i]:=p[j];p[j]:=t;
35 inc(i);dec(j);
36 end;
37 until i>j;
38 if l<j then qsort(l,j);
39 if i<r then qsort(i,r);
40 end;
41 begin
42 assign(input,'wall.in');reset(input);
43 assign(output,'wall.out');rewrite(output);
44 readln(n,l);
45 for i:=1 to n do
46 begin
47 readln(p[i].x,p[i].y);
48 if p[1].y<p[i].y then
49 begin
50 t:=p[1];p[1]:=p[i];p[i]:=t;
51 end;
52 end;
53 qsort(2,n);
54 s.l:=2;
55 s.da[1]:=p[1];s.da[2]:=p[2];
56 for i:=3 to n do
57 begin
58 while (s.l>1)and(leep(s.da[s.l-1],s.da[s.l],p[i])<0) do dec(s.l);
59 inc(s.l);
60 s.da[s.l]:=p[i];
61 end;
62 {while (s.l>1)and(leep(s.da[s.l-1],s.da[s.l],s.da[1])<0) do dec(s.l);
63 k:=1;
64 while (k<s.l-1)and(leep(s.da[s.l],s.da[k],s.da[k+1])<0) do inc(k);
65 r:=0;
66 }
67 for i:=2 to s.l do
68 begin
69 r:=dis(s.da[i],s.da[i-1])+r;
70 end;
71 r:=r+dis(s.da[s.l],s.da[1])+2*pi*l;
72 writeln(r:0:0);
73 close(input);close(output);
74 end.
75