The Wedding Juicer POJ - 2227

采取从外层边界,一步一步向内部拓展的策略,具体来说,一开始将最外面一层的点加入队列,并标记这些点的坐标已经被访问

取出队列中高度最低的点,将其弹出,查看其上下左右的点,如果新点没有被访问过,分两种情况:

1.如果新点的高度大于等于当前点:将新点加入队列,标记新点已经访问过了,该点无法储水

2.如果新点的高度小于当前点:则新点储水(当前点的高度 - 新点的高度),首先,这么多水一定可以存,因为当前点的高度是边界高度中最小的,其次,这是能存的最多的水,因为再多就超过了当前点高度,所以这个点能储存的水,在这种策略下,是所求的最大解,将储水结果累加进ans,并且将这个新点的高度改成当前点的高度后,标记新点坐标已访问,将新点加入队列中

不断重复以上操作,直到队列为空

复杂度略

cpp 复制代码
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;

#define ll long long

const ll maxn=305;
ll w,h,ans;
ll a[maxn][maxn],vis[maxn][maxn];
ll dx[]={-1,1,0,0},dy[]={0,0,-1,1};


struct node{
    ll x,y,h;
    node(ll x=0,ll y=0,ll h=0):x(x),y(y),h(h) {}
    bool operator < (const node &rhs) const {
        return h>rhs.h;
    }
};

int main()
{
    ios::sync_with_stdio(0);cin.tie(0);

    cin>>w>>h;
    for(ll i=1;i<=h;i++){
        for(ll j=1;j<=w;j++){
            cin>>a[i][j];
        }
    }
    priority_queue<node> q;
    //将最外一层加入队列
    for(int i=1;i<=w;i++){
        if(vis[1][i]==0) {
            vis[1][i]=1;
            q.push(node(1,i,a[1][i]));
        }
        if(vis[h][i]==0) {
            vis[h][i]=1;
            q.push(node(h,i,a[h][i]));
        }
    }
    for(int i=1;i<=h;i++){
        if(vis[i][1]==0){
            vis[i][1]=1;
            q.push(node(i,1,a[i][1]));
        }
        if(vis[i][w]==0){
            vis[i][w]=1;
            q.push(node(i,w,a[i][w]));
        }
    }
    /*
    while(q.size()){
        node t=q.top();q.pop();
        printf("(%lld,%lld)\n",t.x,t.y);
    }
    */
    while(q.size()){
        node t=q.top();q.pop();
        ll x=t.x,y=t.y,h1=t.h;
        for(ll i=0;i<4;i++){
            ll nx=x+dx[i],ny=y+dy[i];
            if(nx<1 || nx>h || ny<1 || ny>w) continue;
            if(vis[nx][ny]) continue;
            if(a[nx][ny]>=h1) {
                q.push(node(nx,ny,a[nx][ny]));
                vis[nx][ny]=1;
            }else {
                ans+=h1-a[nx][ny];
                q.push(node(nx,ny,h1));
                vis[nx][ny]=1;
            }
        }
    }
    cout<<ans<<"\n";
    return 0;
}
相关推荐
Gigavision34 分钟前
DEAP数据集 2026最新Transformer算法 DEAP 数据集 下载
深度学习·算法·transformer
夜之眷属1 小时前
PriorityQueue:for-each 遍历和 poll 取出,顺序一样吗?
java·服务器·数据结构·后端·算法
地平线开发者2 小时前
不是线程越多越快:用 hrt_model_exec 在 征程6M 上给 YOLOv5x 建立性能基线
算法
姜鱼问生2 小时前
fail2ban 实战:从默认配置到生产可用
后端·算法·架构
垆边人似月.2 小时前
华为题:全排列
算法·深度优先·图论
杜 硕2 小时前
快速排序详解01
数据结构·算法·排序算法
Matlab程序猿3 小时前
【MATLAB源码-第459期】基于matlab的D-H模型与阻尼最小二乘逆运动学的六自由度机械臂五次轨迹规划及动力学前馈PD控制仿真。
人工智能·算法·matlab·d-h建模·六自由度串联机械臂
信奥卷王3 小时前
[GESP202606 六级] 满二叉树
数据结构·算法
积流成海3 小时前
用代码实现哈希计算器:Web Crypto API 实战
前端·算法·哈希算法·哈希函数·盘子工具站
Nil2083 小时前
leetcode 300最长递增子序列
算法·leetcode·职场和发展