搜索floodfill相关题目时找到的这题,题目可抽象为:一个WxH大小的方块,每个单元为一块,每个单元有一个高度,从正上方向下注水,问最多能装住多少水。
解题思路为,首先最外一圈能装的水量都是0,找出其中最低的,那么与之相邻的(最多四个)方块中,如果比他低,那必可装水至这个块的高度,同时这个装水块的高度上升为那个块的高度。如果比他高或相等,则这块不可装水。然后再找次小的,依次进行,可用优先队列priority_queue来实现,也可以手写堆。
//6935#9044110 helloworld 2227 Accepted 1640K 266MS G++ 2107B 2011-07-31 14:57:52
//9044094 NKHelloWorld 2227 Accepted 1036K 313MS C++ 2062B 2011-07-31 14:56:33
//1A
#include <cstdio>
#include <queue>
using namespace std;
typedef struct
{
int row,col,height;
}NODE;
struct shorter
{
bool operator()(const NODE n1,const NODE n2)
{
return n1.height > n2.height;
}
};
int move[4][2] =
{
-1,0,1,0,0,-1,0,1
};
bool visited[310][310];
int totrow,totcol,map[310][310];
priority_queue<NODE,vector<NODE>,shorter> que;
int main()
{
int i,j,k,row,col;
NODE now;
scanf("%d%d",&totcol,&totrow);
for(i=1;i<=totrow;i++)
for(j=1;j<=totcol;j++)
scanf("%d",&map[i][j]);
for(i=1;i<=totrow;i++)
{
now.row = i; now.col = 1; now.height = map[i][1];
visited[now.row][now.col] = true;
que.push(now);
now.col = totcol; now.height = map[i][totcol];
visited[now.row][now.col] = true;
que.push(now);
}
for(j=2;j<=totcol-1;j++)
{
now.row = 1; now.col = j; now.height = map[1][j];
visited[now.row][now.col] = true;
que.push(now);
now.row = totrow; now.height = map[totrow][j];
visited[now.row][now.col] = true;
que.push(now);
}
int ans = 0;
while(!que.empty())
{
for(i=0;i<4;i++)
{
now.row = que.top().row;
now.col = que.top().col;
now.row += move[i][0];
now.col += move[i][1];
if(!visited[now.row][now.col] && now.row >=1 && now.row <=totrow && now.col >=1 && now.col <= totcol)
{
visited[now.row][now.col] = true;
if(map[now.row][now.col] < que.top().height)
{
ans += que.top().height - map[now.row][now.col];
now.height = que.top().height;
}
else
{
now.height = map[now.row][now.col];
}
que.push(now);
}
}
que.pop();
}
printf("%d\n",ans);
return 0;
}