water(搜尋)
阿新 • • 發佈:2020-08-01
water
題目描述
有一塊矩形土地被劃分成n*m個正方形小塊。這些小塊高低不平,每一小塊都有自己的高度。水流可以由任意一塊地流向周圍四個方向的四塊地中,但是不能直接流入對角相連的小塊中。
一場大雨後,由於地勢高低不同,許多地方都積存了不少降水。給定每個小塊的高度,求每個小塊的積水高度。
注意:假設矩形地外圍無限大且高度為0。
輸入格式
第一行包含兩個非負整數n,m。
接下來n 行每行 個m整數表示第 i行第j列的小塊的高度。
輸出格式
輸出n行,每行m個由空格隔開的非負整數,表示每個小塊的積水高度。
樣例
樣例輸入
3 3
4 4 0
2 1 3
3 3 -1
樣例輸出
0 0 0
0 1 0
0 0 1
資料範圍與提示
對於20%的資料
對於40%的資料
對於60%的資料
對於100%的資料
,|小塊高度|
。
在每一部分資料中,均有一半資料保證小塊高度非負
思路:據題意,找出最外圍一圈小塊若為負,則一定可以積水(因為矩形外邊高度為0,即使旁邊也為負且比它矮,兩個塊也可存水),放入堆中,維護小根堆,一次彈出高度最小的暴搜,若可以存水則標記存水量(注意:存水後要將該塊的高度賦為邊上的塊,因為若高塊將矮塊圍起來,矮塊也能存水 )
1 #include<cstdio> 2 #include<queue> 3 #include<algorithm> 4 using namespace std; 5 const int maxn=300+10; 6 typedef long long ll; 7 ll a[maxn][maxn],vis[maxn][maxn],b[maxn][maxn];//vis標記該塊有無入堆 8 int ans=0,n,m; 9 struct Node{ 10 int x,y,w; 11 Node(){}; 12 Node(intView Codea,int b,int c){ 13 x=a; 14 y=b; 15 w=c; 16 } 17 bool operator<(const Node &a)const{ 18 return w>a.w; 19 } 20 };//過載維護小根堆 21 priority_queue<Node> q; 22 void Init(){ 23 scanf("%d%d",&n,&m); 24 for(int i=1;i<=n;i++){ 25 for(int j=1;j<=m;j++){ 26 scanf("%lld",&a[i][j]); 27 if(i==1||j==1||i==n||j==m){ 28 if(a[i][j]<0&&!b[i][j]){ 29 b[i][j]-=a[i][j]; 0 0 0 30 a[i][j]=0;//注意置為0,不然若圖為 0 -2 -10 若-10未置0,-2就不能存水 31 } 0 0 0 32 if(!vis[i][j])q.push((Node){i,j,a[i][j]}); 33 vis[i][j]=1; 34 } 35 } 36 } 37 } 38 void solve(){ 39 while(!q.empty()){ 40 Node u=q.top(); 41 q.pop(); 42 int x=u.x; 43 int y=u.y; 44 int w=u.w; 45 if(y+1<=m&&!vis[x][y+1]){//右邊 46 if(a[x][y+1]>=w) q.push((Node){x,y+1,a[x][y+1]});//不能寫continue,這樣迴圈就結束了而不是 47 else { //只if語句結束 48 b[x][y+1]+=(w-a[x][y+1]); 49 a[x][y+1]=w; 50 q.push((Node){x,y+1,w}); 51 } 52 vis[x][y+1]=1; 53 } 54 if(x-1>=1&&!vis[x-1][y]){//上邊 55 if(a[x-1][y]>=w) q.push((Node){x-1,y,a[x-1][y]}); 56 else{ 57 b[x-1][y]+=(w-a[x-1][y]); 58 a[x-1][y]=w; 59 q.push((Node){x-1,y,w}); 60 } 61 vis[x-1][y]=1; 62 } 63 if(x+1<=n&&!vis[x+1][y]){//下邊 64 if(a[x+1][y]>=w) q.push((Node){x+1,y,a[x+1][y]}); 65 else{ 66 b[x+1][y]+=(w-a[x+1][y]); 67 a[x+1][y]=w; 68 q.push((Node){x+1,y,w}); 69 } 70 vis[x+1][y]=1; 71 } 72 if(y-1>=1&&!vis[x][y-1]){//左邊 73 if(a[x][y-1]>=w) q.push((Node){x,y-1,a[x][y-1]}); 74 else{ 75 b[x][y-1]+=(w-a[x][y-1]); 76 a[x][y-1]=w; 77 q.push((Node){x,y-1,w}); 78 } 79 vis[x][y-1]=1; 80 } 81 } 82 } 83 void print(){ 84 for(int i=1;i<=n;i++){ 85 for(int j=1;j<=m;j++){ 86 printf("%lld ",b[i][j]); 87 } 88 printf("\n"); 89 } 90 } 91 int main(){ 92 Init(); 93 solve(); 94 print(); 95 return 0; 96 }