|
这题看了以后,想了一个很脑残的做法,也过了,不过用了1.2s,哈哈。 后来看了一个高中生大牛写的 Pascal 程序。 根据函数名字来看,它用的是 floodfill 算法,提交了发现居然才用了188ms。 现在高中生真太牛逼了!佩服! 同时,作为一个即将毕业的大学生,哥表示压力很大。。 以前没见过这个算法,看了一下,发现看不大懂,但是这样做确实很有道理! 在网上面搜了一下关于floodfill算法的资料,发现很杂,还是看不大懂。。
算法的思想就是: 每个点都有一个水位,水位最小值为这个点的高度。 首先把边缘一周的点加入堆,这些点的水位初始化为点的高度。 每次都取出最小水位的点,将点周围的四个点里面,从来没有被加入过堆的点加入堆中,如果有的点的高度比水位低,那么就更新答案。 删除最小水位的点,然后重复上一步。直到不存在没有被加入过堆中的点为止。
用 C 再写了一遍,小小改动,慢了 100ms。
#include <stdio.h>

#define SIZE 332

 struct heap_node {
int x, y;
};

int W, H;
int map[SIZE][SIZE], fil[SIZE][SIZE];
struct heap_node heap[SIZE * SIZE];
int heap_size, left, ans;

inline int cmp(struct heap_node *a, struct heap_node *b)
  {
return fil[a->y][a->x] - fil[b->y][b->x];
}

inline void shift_down(int idx)
  {
struct heap_node val = heap[idx];
 while (1) {
idx *= 2;
if (idx > heap_size)
break;
if (idx + 1 <= heap_size && cmp(&heap[idx + 1], &heap[idx]) < 0)
idx++;
if (cmp(&val, &heap[idx]) <= 0)
break;
heap[idx / 2] = heap[idx];
}
heap[idx / 2] = val;
}

inline void shift_up(int idx)
  {
struct heap_node val = heap[idx];
 while (1) {
if (idx / 2 <= 0)
break;
if (cmp(&heap[idx / 2], &val) <= 0)
break;
heap[idx] = heap[idx / 2];
idx /= 2;
}
heap[idx] = val;
}

inline void insert(int y, int x, int f = -1)
  {
if (y < 0 || y >= H || x < 0 || x >= W || fil[y][x])
return ;
if (map[y][x] > f)
f = map[y][x];
else
ans += f - map[y][x];
fil[y][x] = f;
heap_size++;
heap[heap_size].y = y;
heap[heap_size].x = x;
shift_up(heap_size);
left--;
}

inline void extract()
  {
heap[1] = heap[heap_size--];
shift_down(1);
}

int main()
  {
int i, j;

freopen("e:\\test\\in.txt", "r", stdin);

scanf("%d%d", &W, &H);
for (i = 0; i < H; i++)
for (j = 0; j < W; j++)
scanf("%d", &map[i][j]);
left = W * H;
 for (i = 0; i < H; i++) {
insert(i, 0);
insert(i, W - 1);
}
 for (i = 1; i < W - 1; i++) {
insert(0, i);
insert(H - 1, i);
}

 while (left) {
i = heap[1].y;
j = heap[1].x;
extract();
insert(i - 1, j, fil[i][j]);
insert(i + 1, j, fil[i][j]);
insert(i, j - 1, fil[i][j]);
insert(i, j + 1, fil[i][j]);
}

printf("%d\n", ans);

return 0;
}
Pascal:
Pascal:
  {$m $100000} {由于我是做的DFS进行FLOODFILL,所以不免开了点栈深度}

Program Gp ;

const
maxn = 300 ;
dx : array[ 0 .. 3 ] of -1 .. 1 = ( 0 , 1 , 0 , -1 ) ;
dy : array[ 0 .. 3 ] of -1 .. 1 = ( 1 , 0 , -1 , 0 ) ;
zy = trunc( 1e9 ) ;

type
heaptype =
record
x , y , val : longint ;
end ;

var
map , f : array[ 0 .. maxn , 0 .. maxn ] of longint ;
use , u : array[ 0 .. maxn , 0 .. maxn ] of boolean ;
heap : array[ 0 .. maxn * maxn ] of heaptype ;
n , m , ans , len : longint ;
cant : boolean ;

procedure init ;
var
i , j : longint ;
begin
fillchar( f , sizeof( f ) , 0 ) ;
readln( m , n ) ;
for i := 1 to n do
for j := 1 to m do
begin
read( map[ i , j ] ) ; f[ i , j ] := zy ;
end ;
end ;

procedure ins( x , y , val : longint ) ;
var
t : heaptype ;
i : longint ;
begin
t.x := x ; t.y := y ; t.val := val ;
inc( len ) ; i := len ;
while ( i <> 1 ) and ( heap[ i div 2 ] . val > val ) do
begin
heap[ i ] := heap[ i div 2 ] ;
i := i div 2 ;
end ;
heap[ i ] := t ;
end ;

procedure sort( ii : longint ) ;
var
j : longint ;
num : heaptype ;
begin
num := heap[ ii ] ;
j := ii * 2 ;
while j <= len do
begin
if ( j < len ) and ( heap[ j ] . val > heap[ j + 1 ] . val ) then inc( j ) ;
if num . val > heap[ j ] . val then
begin
heap[ ii ] := heap[ j ] ;
ii := j ;
j := ii * 2 ;
end else break ;
end ;
heap[ ii ] := num ;
end;

procedure dfs( x , y , max , deep : longint ) ;
var
i , xx , yy : longint ;
begin
u[ x , y ] := false ;
if ( max < f[ x , y ] ) then f[ x , y ] := max ;
for i := 0 to 3 do
begin
xx := x + dx[ i ] ; yy := y + dy[ i ] ;
if ( xx <= 0 ) or ( xx > n ) or ( yy <= 0 ) or ( yy > m ) or ( not u[ xx , yy ] ) then continue ;
if map[ xx , yy ] <= max then dfs( xx , yy , max , deep + 1 )
else begin
if use[ xx , yy ] then
begin
ins( xx , yy , map[ xx , yy ] ) ;
use[ xx , yy ] := false ;
end ;
end ;
end ;
end ;

procedure floodfill( x : heaptype ) ;
var
cici , i , a , b : longint ;
begin
if f[ x.x , x.y ] = zy then f[ x.x , x.y ] := map[ x.x , x.y ] ;
dfs( x.x , x.y , f[ x.x , x.y ] , 1 ) ;
end ;

procedure solve ;
var
i , j : longint ;
now : heaptype ;
begin
fillchar( u , sizeof( u ) , true ) ;
fillchar( use , sizeof( use ) , true ) ;
len := 0 ;
for i := 1 to n do
begin
if use[ i , 1 ] then ins( i , 1 , map[ i , 1 ] ) ; use[ i , 1 ] := false ; f[ i , 1 ] := map[ i , 1 ] ;
if use[ i , m ] then ins( i , m , map[ i , m ] ) ; use[ i , m ] := false ; f[ i , m ] := map[ i , m ] ;
end ;
for i := 1 to m do
begin
if use[ 1 , i ] then ins( 1 , i , map[ 1 , i ] ) ; use[ 1 , i ] := false ; f[ 1 , i ] := map[ 1 , i ] ;
if use[ n , i ] then ins( n , i , map[ n , i ] ) ; use[ n , i ] := false ; f[ n , i ] := map[ n , i ] ;
end ;
while len > 0 do
begin
now := heap[ 1 ] ; heap[ 1 ] := heap[ len ] ;
heap[ len ] . val := maxlongint ; dec( len ) ;
sort( 1 ) ;
floodfill( now ) ;
end ;
end ;

procedure print ;
var
i , j , ans : longint ;
begin
ans := 0 ;
for i := 1 to n do
for j := 1 to m do inc( ans , f[ i , j ] - map[ i , j ] ) ;
writeln( ans ) ;
end ;

procedure main ;
begin
init ;
solve ;
print ;
end ;

Begin
main ;
end .
|