zoukankan      html  css  js  c++  java
  • Jzoj P5830 water (优先队列BFS)

    Description

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

    Input

    第一行包含两个非负整数 n,m。 接下来 n 行每行 m 个整数表示第 i 行第 j 列的小块的高度。
    Output
    输出 n 行,每行 m 个由空格隔开的非负整数,表示每个小块的积 水高度。

    Sample Input

    3 3
    4 4 0
    2 1 3
    3 3 -1
    

    Sample Output

    0 0 0
    0 1 0
    0 0 1 
    

    Data Constraint

    对于 20%的数据 n,m<=4
    对于 40%的数据 n,m<=15
    对于 60%的数据 n,m<=50
    对于 100%的数据 n,m<=300,|小块高度|<=10^9。
    在每一部分数据中,均有一半数据保证小块高度非负

    Solution

    首先将所有小于0的补为0,将边上一圈作为边界放入堆,然后向内拓展,因为每次都是取最矮的边界,所以是正确的,且每块地只被更新一次
    代码中有注释,或许可以解决一些问题

    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #include <cmath>
    #include <cstring>
    using namespace std;
    const int maxn=300+5;
    int n,m;
    int h[maxn][maxn];
    int ans[maxn][maxn];
    bool vis[maxn][maxn];
    int dx[]={0,-1,0,0,1};
    int dy[]={0,0,-1,1,0};
    struct Node{
    	int x,y,val;
    	Node(){}
    	Node(int _x,int _y,int _val){
    		x=_x,y=_y,val=_val;
    	}
    	bool operator < (const Node &B)const{
    		return val>B.val;
    	}
    };
    priority_queue <Node> q;
    int main(){
    	//freopen("1.in","r",stdin);
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=m;++j){
    			scanf("%d",&h[i][j]);
    			if(h[i][j]<0) ans[i][j]+=(-h[i][j]),h[i][j]=0; //先填为0,好处理,因为最后至少是0
    			if(i==1||i==n||j==1||j==m) q.push(Node(i,j,h[i][j])),vis[i][j]=1;//将出口入堆
    		}
    	}
    	int x,y,val;
    	while(!q.empty()){
    		x=q.top().x; y=q.top().y; val=q.top().val; q.pop();
    		for(int i=1,rx,ry;i<=4;++i){
    			rx=x+dx[i]; ry=y+dy[i];
    			if(vis[rx][ry] || rx<1 || rx>n || ry<1 || ry>m) continue; //目标点不合法或已搜过
    			if(val>h[rx][ry]) ans[rx][ry]+=(val-h[rx][ry]); //目标点比当前低,累加答案
    			vis[rx][ry]=1;
    			q.push(Node(rx,ry,max(h[rx][ry],val)));// 向内拓展,不用担心取max会使结果错误,因为每次从堆中取的点都是最低的
    		}
    	}
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=m;++j){
    			printf("%d ",ans[i][j]);
    		}
    		printf("
    ");
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    day12 Python操作rabbitmq及pymsql
    day11 队列、线程、进程、协程及Python使用缓存(redis/memcache)
    day10 Python作用域 Python2.7与Python3.x的类继承的区别、异步IO、多进程,多线程简介
    day09 Python socket编程
    day08 面向对象补充及单例模式
    day07 configparser xml subprocess 面向对象
    day06 Python的一些内建变量、反射、hashlib模块、re模块、os模块、sys模块
    day05 Python多层装饰器、模块、序列化、字符串格式化、生成器和迭代器、递归、time、datetime模块、logging模块
    day04 Python一些内置函数及装饰器
    查看旧版jexus命令
  • 原文地址:https://www.cnblogs.com/Lour688/p/13415262.html
Copyright © 2011-2022 走看看