1 条题解

  • 0
    @ 2026-9-28 14:40:42

    这道题其实是一道水绿。

    经过同机房大佬 yuruilin2026 的指导,成功 A 了这道水题。

    做题思路

    从边界开始,找到边界的最矮砖块 ii,检查他的邻居砖块 jj:

    1. 如果 hi≤hjh_i \le h_j,jj 不能储水将 jj 作为新的边界;
    2. 如果 hi>hjh_i>h_j,则该块可以储水,出水量增加 hi−hjh_i - h_j,把 jj 的高度改为 ii 的高度将 jj 作为新的边界。

    每次检查最矮的砖块,用优先队列实现。

    代码实现

    具体看代码。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e3+5;
    int n,m;
    int a[N][N],fx[4][2]={{1,0},{0,1},{-1,0},{0,-1}},ans=0; 
    bool vis[N][N];
    struct node{
    	int x,y;
    	bool operator <(const node&s)const{
    		return a[x][y]>a[s.x][s.y];
    	}
    };
    priority_queue<node> q;
    void bfs()
    {
    	
    	for(int i=2;i<n;i++)
    	{
    		q.push({i,1});
    		q.push({i,m});
    		vis[i][1]=true;vis[i][m]=true;
    	}
    	for(int i=2;i<m;i++)
    	{
    		q.push({1,i});
    		q.push({n,i});
    		vis[1][i]=true;vis[n][i]=true;
    	}
    	vis[1][1]=vis[n][1]=vis[1][m]=vis[n][m]=true;
    	while(!q.empty())
    	{
    		node t=q.top();
    		q.pop();
    		int x=t.x,y=t.y;
    		for(int i=0;i<4;i++)
    		{
    			int x_x=x+fx[i][0];
    			int x_y=y+fx[i][1];
    			if(x_x>=1&&x_y>=1&&x_x<=n&&x_y<=m&&!vis[x_x][x_y])
    			{
    				//cout<<x_x<<" "<<x_y<<endl;
    				vis[x_x][x_y]=true;
    				if(a[x][y]>=a[x_x][x_y])
    				{
    					ans+=a[x][y]-a[x_x][x_y];
    					a[x_x][x_y]=a[x][y]; 
    				}
    				q.push({x_x,x_y});
    			}
    		}
    	}
    }
    int main()
    {
    	cin>>m>>n;
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=1;j<=m;j++)
    		{
    			cin>>a[i][j];
    		}
    	}
    	bfs();
    	cout<<ans;
    }
    
    • 1

    信息

    ID
    2178
    时间
    1000ms
    内存
    128MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者