搜索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; }