Viaky
Hope,is there.

题目大意:

有一篇凹凸不平的矩形地面,面积为m*n,被分为M*N个小正方形,每个正方形有不同的高度,如图所示

给出矩形中每个正方形的高度,若一场雨后,这块矩形地面最多能积多少体积的水。

解题思路:

不断地去找最低的那个小块进行灌水,这是肯定的。

由于需要一直找最小值,所以用到最小堆来进行优化。

初始化,边界是肯定不能积水的,因为肯定会流出来。所以在一开始所有的边界都设置为已访问标记。将边界上所有的点都加进堆里,并不断地调整堆。

在边界中取最低的那一个小块进行扩展,记录这个最小的节点高度为t ,扩展到的内部节点如果比t小,那么就灌水,也就是将扩展到的节点高度上升到t,不要忘了统计ans。并同时将上升后的点加进堆。如果扩展到的点比t高,也就相当于一个边界,将这个点直接加进堆。

参考代码:

  1   const
2 dx:array[1..4] of longint=(0,0,1,-1);
3 dy:array[1..4] of longint=(1,-1,0,0);
4 type
5 tt=record
6 x,y,t:longint;
7 end;
8 var
9 d:array[1..250000] of tt;
10 v:array[0..505,0..505] of boolean;
11 a:array[0..505,0..505] of longint;
12 n,m,i,j,tot,open,x,y,xx,yy,t:longint;
13 ans:int64;
14 procedure swap(x,y:longint);
15 var
16 t:tt;
17 begin
18 t:=d[x]; d[x]:=d[y]; d[y]:=t;
19 end;
20 procedure up(i:longint);
21 var
22 j:longint;
23 begin
24 while i>1 do
25 begin
26 j:=i div 2;
27 if d[i].t<d[j].t then swap(i,j) else break;
28 i:=j;
29 end;
30 end;
31 procedure down(i:longint);
32 var
33 j:longint;
34 begin
35 while i<=tot div 2 do
36 begin
37 j:=i*2;
38 if (d[j].t>d[j+1].t) and (j+1<=tot) then inc(j);
39 if d[i].t>d[j].t then swap(i,j) else break;
40 i:=j;
41 end;
42 end;
43 begin
44 assign(input,'pail.in');reset(input);
45 assign(output,'pail.out');rewrite(output);
46
47 readln(m,n);
48 for i:=1 to n do
49 for j:=1 to m do
50 read(a[i,j]);
51 for i:=1 to m do
52 begin
53 inc(tot);
54 v[1,i]:=true;
55 d[tot].t:=a[1,i];
56 d[tot].x:=1;
57 d[tot].y:=i;
58 up(tot);
59
60 inc(tot);
61 v[n,i]:=true;
62 d[tot].t:=a[n,i];
63 d[tot].x:=n;
64 d[tot].y:=i;
65 up(tot);
66 end;
67 for i:=2 to n-1 do
68 begin
69 inc(tot);
70 v[i,1]:=true;
71 d[tot].t:=a[i,1];
72 d[tot].x:=i;
73 d[tot].y:=1;
74 up(tot);
75
76 inc(tot);
77 v[i,m]:=true;
78 d[tot].t:=a[i,m];
79 d[tot].x:=i;
80 d[tot].y:=m;
81 up(tot);
82 end;
83 while tot<n*m do
84 begin
85 x:=d[1].x;
86 y:=d[1].y;
87 t:=d[1].t;
88 d[1].t:=maxlongint;
89 down(1);
90 for i:=1 to 4 do
91 begin
92 xx:=x+dx[i];
93 yy:=y+dy[i];
94 if (xx>0) and (xx<=n) and (yy>0) and (yy<=m) then
95 if not v[xx,yy] then
96 begin
97 inc(tot);
98 d[tot].x:=xx;
99 d[tot].y:=yy;
100 if t>a[xx,yy] then begin
101 inc(ans,t-a[xx,yy]);
102 d[tot].t:=t;
103 end
104 else d[tot].t:=a[xx,yy];
105 up(tot);
106 v[xx,yy]:=true;
107 end;
108 end;
109 end;
110 writeln(ans);
111 close(input);
112 close(output);
113
114 end.

Viaky原创。请勿copy。 

posted on 2011-08-11 19:48  Viaky  阅读(548)  评论(0编辑  收藏  举报