题意:一个矩形区域,高低起伏,求最多储水量。(边界不能储水)
题解:先将边界装入优先队列中(高度越小越优先),并标记为已访问。看队首元素四周未访问过的点,1、如果该点不比队首低,则将它加入队列,标记为已访问,即它变成了新的边界。2、该点比队首低,意味着该点可以储水,更新ans值,同时将它加入队列中,但是它的高度为原队首元素的高度,即以它为边界的点不能超过这个高度,同时将该点标记为已访问。
View Code
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<queue> 5 using namespace std; 6 int r,c; 7 typedef long long ll; 8 ll map[400][400]; 9 struct Data 10 { 11 int x,y; 12 ll h; 13 bool operator<(const Data &ne)const 14 { 15 return h>ne.h; 16 } 17 Data(){}; 18 Data(int _x,int _y,ll _h) 19 { 20 x=_x; 21 y=_y; 22 h=_h; 23 } 24 }; 25 priority_queue<Data> Q; 26 int dr[][2]={0,1,0,-1,1,0,-1,0}; 27 bool in(int x,int y) 28 { 29 return x>=1&&x<=r&&y>=1&&y<=c; 30 } 31 int main() 32 { 33 while(scanf("%d%d",&c,&r)!=EOF) 34 { 35 for(int i=1;i<=r;i++) 36 { 37 for(int j=1;j<=c;j++) 38 { 39 scanf("%lld",&map[i][j]); 40 } 41 } 42 while(!Q.empty()) 43 Q.pop(); 44 for(int i=1;i<=r;i++) 45 { 46 Q.push(Data(i,1,map[i][1])); 47 Q.push(Data(i,c,map[i][c])); 48 map[i][1]=-1; 49 map[i][c]=-1; 50 } 51 for(int i=1;i<=c;i++) 52 { 53 Q.push(Data(1,i,map[1][i])); 54 Q.push(Data(r,i,map[r][i])); 55 map[1][i]=-1; 56 map[r][i]=-1; 57 } 58 long long ans=0; 59 while(!Q.empty()) 60 { 61 Data a=Q.top(),b; 62 Q.pop(); 63 for(int i=0;i<4;i++) 64 { 65 b.x=a.x+dr[i][0]; 66 b.y=a.y+dr[i][1]; 67 if(in(b.x,b.y)) 68 { 69 ll tp=map[b.x][b.y]; 70 if(tp==-1) 71 continue; 72 else if(tp<a.h) 73 { 74 ans+=a.h-tp; 75 } 76 b.h=max(tp,a.h); 77 Q.push(b); 78 map[b.x][b.y]=-1; 79 } 80 } 81 } 82 printf("%lld\n",ans); 83 } 84 return 0; 85 }