zoukankan      html  css  js  c++  java
  • [CSP-S模拟测试]:water(BFS)

    题目描述

    有一块矩形土地被划分成$n imes 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\%$的数据$n,mleqslant 4$。
    对于$40\%$的数据$n,mleqslant 15$。
    对于$60\%$的数据$n,mleqslant 50$。
    对于$100\%$的数据$n,mleqslant 300$,$|$小块高度$|leqslant {10}^9$。
    在每一部分数据中,均有一半数据保证小块高度非负。


    题解

    首先需要明确一个问题,每一个块的最终高度就是所有从这个块走出这个矩形当中的最大高度的最小值(通读左边这句话三遍!!!)。

    然后我利用了类似$SPFA$的思想进行$BFS$,先将最外面一圈加入队列,然后去更新它所能更新四个点的答案,如果一个点被更新,那么就重新将这个点压入队列即可。

    时间复杂度:$Theta(n imes m imes k)$($k$为较小常数,其实时间复杂度我也不太会证,毕竟是类$SPFA$思想)。

    期望得分:$100$分。

    实际得分:$100$分。


    代码时刻

    #include<bits/stdc++.h>
    using namespace std;
    int n,m;
    long long Map[500][500];
    long long dis[500][500];
    queue<pair<int,int> > q;
    void BFS()
    {
    	while(!q.empty())
    	{
    		pair<int,int> flag=q.front(),wzc;
    		q.pop();
    		wzc=make_pair(flag.first-1,flag.second);
    		if(wzc.first>1&&wzc.second>1&&wzc.first<n&&wzc.second<m)
    			if(dis[wzc.first][wzc.second]>max(Map[wzc.first][wzc.second],dis[flag.first][flag.second]))
    			{
    				dis[wzc.first][wzc.second]=max(Map[wzc.first][wzc.second],dis[flag.first][flag.second]);
    				q.push(wzc);
    			}
    		wzc=make_pair(flag.first,flag.second-1);
    		if(wzc.first>1&&wzc.second>1&&wzc.first<n&&wzc.second<m)
    			if(dis[wzc.first][wzc.second]>max(Map[wzc.first][wzc.second],dis[flag.first][flag.second]))
    			{
    				dis[wzc.first][wzc.second]=max(Map[wzc.first][wzc.second],dis[flag.first][flag.second]);
    				q.push(wzc);
    			}
    		wzc=make_pair(flag.first+1,flag.second);
    		if(wzc.first>1&&wzc.second>1&&wzc.first<n&&wzc.second<m)
    			if(dis[wzc.first][wzc.second]>max(Map[wzc.first][wzc.second],dis[flag.first][flag.second]))
    			{
    				dis[wzc.first][wzc.second]=max(Map[wzc.first][wzc.second],dis[flag.first][flag.second]);
    				q.push(wzc);
    			}
    		wzc=make_pair(flag.first,flag.second+1);
    		if(wzc.first>1&&wzc.second>1&&wzc.first<n&&wzc.second<m)
    			if(dis[wzc.first][wzc.second]>max(Map[wzc.first][wzc.second],dis[flag.first][flag.second]))
    			{
    				dis[wzc.first][wzc.second]=max(Map[wzc.first][wzc.second],dis[flag.first][flag.second]);
    				q.push(wzc);
    			}
    	}
    }
    int main()
    {
    	memset(dis,0x3f,sizeof(dis));
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    			scanf("%lld",&Map[i][j]);
    	for(int i=1;i<=n;i++)
    	{
    		dis[i][1]=max(0LL,Map[i][1]);
    		dis[i][m]=max(0LL,Map[i][m]);
    		q.push(make_pair(i,1));
    		q.push(make_pair(i,m));
    	}
    	for(int i=1;i<=m;i++)
    	{
    		dis[1][i]=max(0LL,Map[1][i]);
    		dis[n][i]=max(0LL,Map[n][i]);
    		q.push(make_pair(1,i));
    		q.push(make_pair(n,i));
    	}
    	BFS();
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=1;j<=m;j++)
    			printf("%lld ",max(0LL,dis[i][j]-Map[i][j]));
    		puts("");
    	}
    	return 0;
    }
    

    rp++

  • 相关阅读:
    服务器编程
    前端了解
    requests.post( )发送日志
    python---split函数
    Shell等待提示符"#"和"$"
    数据文件格式对读写速度的影响
    指针常量和常量指针的区别
    C++ 类构造函数 & 析构函数
    2016word多级列表 一级标题居中后偏左
    word交叉引用公式编号时和连公式一起引用
  • 原文地址:https://www.cnblogs.com/wzc521/p/11380805.html
Copyright © 2011-2022 走看看