天天看点

解题报告 黑书 Water pail poi 1999

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