• water(搜索)


                                                         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(int a,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("
    ");
    89     }
    90 }
    91 int main(){
    92     Init();
    93     solve();
    94     print();
    95     return 0;
    96 }
    View Code
  • 相关阅读:
    golang学习笔记(7)--函数式编程
    golang学习笔记(6)--面向接口编程
    go语言学习笔记(5)--面向对象
    go语言学习笔记(4)--容器与字符串的基本概念
    go语言学习笔记(3)--简单的程序设计
    go语言学习笔记(2)--go语言语法细节与基本数据类型
    go语言学习笔记(1)--第一个go语言程序
    Linux学习笔记系列(1)
    Scrapy爬虫小demo总结
    python基础总结(6)
  • 原文地址:https://www.cnblogs.com/HZOIDJ123/p/13416745.html
Copyright © 2020-2023  润新知