• [10.10模拟] water


    题意:

    有一块矩形土地被划分成 n*m 个正方形小块。这些小块高低不平,每一小块都有自己的高度。水流可以由任意一块地流向周围四个方向的四块地中,但是不能直接流入对角相连的小块中。一场大雨后,由于地势高不同,许多地方都积存了不少降水。给定每个小块的高度,求每个小块的积水高度。注意:假设矩形地外围无限大且高度为 0。

    题解:

    思维

    可以想象水就是每次从某个比较高的块上,流向别的比它低的块,直到把这个坑填满,我们称这个块为初始块......

    而初始块应当是这个坑中周围一圈的块中的最小值,所以可以用堆来维护这个块

    从初始块开始,流向所有比它低的块,直到把坑填满,若遇到了比它高的块,则这个块可能会成为另外一个坑的初始块,所以把它加入堆

    每次从堆中弹出一个初始块,bfs把这个初始快能填的坑填满

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #define ll long long
    #define N 310
    using namespace std;
    
    int n,m;
    int g[N][N],f[N][N],dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
    bool in[N][N],vis[N][N];
    
    struct Node {
      int x,y,h;
      bool operator < (const Node &a) const {
        return h>a.h;
      }
    };
    
    priority_queue<Node> pq;
    queue<pair<int,int> > q;
    
    int gi() {
      int x=0,o=1; char ch=getchar();
      while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
      if(ch=='-') o=-1,ch=getchar();
      while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
      return o*x;
    }
    
    void bfs(int x, int y) {
      q.push(make_pair(x,y));
      while(!q.empty()) {
        int qx=q.front().first,qy=q.front().second;
        q.pop();
        for(int i=0; i<4; i++) {
          int xx=qx+dx[i],yy=qy+dy[i];
          if(!(xx>=1 && xx<=n && yy>=1 && yy<=m && !vis[xx][yy])) continue;
          vis[xx][yy]=1;
          if(f[x][y]>=f[xx][yy]) f[xx][yy]=f[x][y],q.push(make_pair(xx,yy));
          else pq.push((Node){xx,yy,f[xx][yy]});
        }
      }
    }
    
    int main() {
      n=gi(),m=gi();
      for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++)
          g[i][j]=gi(),f[i][j]=max(g[i][j],0);
      vis[1][1]=vis[1][m]=vis[n][1]=vis[n][m]=1;
      for(int i=2; i<n; i++) {
        pq.push((Node){i,1,f[i][1]});
        pq.push((Node){i,m,f[i][m]});
        vis[i][1]=vis[i][m]=1;
      }
      for(int i=2; i<m; i++) {
        pq.push((Node){1,i,f[1][i]});
        pq.push((Node){n,i,f[n][i]});
        vis[1][i]=vis[n][i]=1;
      }
      while(!pq.empty()) {
        Node now=pq.top();
        pq.pop();
        bfs(now.x,now.y);
      }
      for(int i=1; i<=n; i++) {
        for(int j=1; j<=m; j++)
          printf("%d ", f[i][j]-g[i][j]);
        printf("
    ");
      }
      return 0;
    }
    
  • 相关阅读:
    Oracle的并发多版本 读一致性
    挖掘ADO.NET Entity框架的性能
    System.Linq扩张方法Where (Lambda表达式)
    LINQ与HQL (二)
    HQL查询中的几个函数
    LINQ 与 HQL (一)
    C# 3.0的新特性(一)
    共享锁 排他锁
    Psytopic测试
    这些地方才是真正值得去的
  • 原文地址:https://www.cnblogs.com/HLXZZ/p/7648334.html
Copyright © 2020-2023  润新知