1. 题目
4.water pail
题目描述:
Zz同学家里有一个奇怪的水桶,这个水桶不是圆柱型的,它的底面是一个长方形,合格长方形是由n*m个格子构成的,这个水桶更奇怪的地方是水桶内的每个格子的高度都是不同的。既然是水桶,那么Zz同学请你求出这个水桶最多能装多少体积的水
输入:
第一行两个正整数n,m (0<n,m<=300)
接下来是一个n*m的矩形,I行j列的数字代表水桶内该格子的高度h(0<=h<=1 000 000 000)
输出:
最多装水的体积
样例:
输入:
4 5
5 8 7 7
5 2 1 5
7 1 7 1
8 9 6 9
9 8 9 9
输出:
12
数据范围:
对于30%的数据
1<=n,m<=10
对于100%的数据
1<=n<=500
1<=m<=500
2. 题目实质
这个,就是灌水。
难道这就是 Floodfill 的原型?
3. 算法
floodfill + 队列 + 堆优化
首先,在边缘的一圈找到一个最小的点,然后从这个点(先从小到大选择边缘上的点,然后再往里选,这个用队列来维护)开始 floodfill ,扩展那些比他小的点(将他们赋为这个点的值,再将这个点赋为 maxlongint ,这样能够保证以后不会再一次扩展到他),然后将扩展的所有点入队(因为不能再扩展了,队列存的是不能再扩展的点),然后每次找队列中最小的点(维护队列的队首元素是最小的,但不能用单调队列的方法维护,那样会改变元素个数,就正常的维护)进行扩展,依此类推。
注意这个数据比较变态,所以维护队列时要用到堆。
4. 注意事项
要用堆优化。
5. 程序代码
dsqwee (pascal)
program dsqwwe;
const
dx:array[1..4] of longint=(0,0,1,-1);
dy:array[1..4] of longint=(1,-1,0,0);
type
tt=record
x,y,t:longint;
end;
var
d:array[1..250000] of tt;
v:array[0..505,0..505] of boolean;
a:array[0..505,0..505] of longint;
n,m,i,j,tot,open,x,y,xx,yy,t:longint;
ans:int64;
procedure swap(x,y:longint);
var
t:tt;
begin
t:=d[x]; d[x]:=d[y]; d[y]:=t;
end;
procedure up(i:longint);
var
j:longint;
begin
while i>1 do
begin
j:=i div 2;
if d[i].t<d[j].t then swap(i,j) else break;
i:=j;
end;
end;
procedure down(i:longint);
var
j:longint;
begin
while i<=tot div 2 do
begin
j:=i*2;
if (d[j].t>d[j+1].t) and (j+1<=tot) then inc(j);
if d[i].t>d[j].t then swap(i,j) else break;
i:=j;
end;
end;
begin
assign(input,'pail.in');reset(input);
assign(output,'pail.out');rewrite(output);
readln(m,n);
for i:=1 to n do
for j:=1 to m do
read(a[i,j]);
for i:=1 to m do
begin
inc(tot);
v[1,i]:=true;
d[tot].t:=a[1,i];
d[tot].x:=1;
d[tot].y:=i;
up(tot);
inc(tot);
v[n,i]:=true;
d[tot].t:=a[n,i];
d[tot].x:=n;
d[tot].y:=i;
up(tot);
end;
for i:=2 to n-1 do
begin
inc(tot);
v[i,1]:=true;
d[tot].t:=a[i,1];
d[tot].x:=i;
d[tot].y:=1;
up(tot);
inc(tot);
v[i,m]:=true;
d[tot].t:=a[i,m];
d[tot].x:=i;
d[tot].y:=m;
up(tot);
end;
while tot<n*m do
begin
x:=d[1].x;
y:=d[1].y;
t:=d[1].t;
d[1].t:=maxlongint;
down(1);
for i:=1 to 4 do
begin
xx:=x+dx[i];
yy:=y+dy[i];
if (xx>0) and (xx<=n) and (yy>0) and (yy<=m) then
if not v[xx,yy] then
begin
inc(tot);
d[tot].x:=xx;
d[tot].y:=yy;
if t>a[xx,yy] then begin
inc(ans,t-a[xx,yy]);
d[tot].t:=t;
end
else d[tot].t:=a[xx,yy];
up(tot);
v[xx,yy]:=true;
end;
end;
end;
writeln(ans);
close(input);
close(output);
end.
转载于:https://www.cnblogs.com/SueMiller/archive/2011/08/11/2135281.html