建设围墙 (wall.pas)题解

建设围墙 (wall.pas)

 

学校要为一栋教学楼建围墙

  

为了美观,围墙离楼的距离不能小于一个常数L,求如何建造围墙最节省材料

 

Input (wall.in)

第一行两个整数NLN表示教学楼的顶点个数

接下来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<=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<then qsort(l,j);
39      if i<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])<0do 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 

 

posted @ 2009-10-25 18:26  瀑布飞鹰  阅读(295)  评论(0编辑  收藏  举报