建设围墙 (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