0
点赞
收藏
分享

微信扫一扫

贪心算法之容器/地形装水

东林梁 2022-02-27 阅读 23

由打包机器人(业务题)我们可以知道单点指标法和网络节流法(单点最痛问题即为全局问题解)
在这里插入图片描述
一维情况:
单点指标法,一个点一个点来算它上面的水,它上面的水取决于左边最大值和右边最大值的最小值。
我们用双指针,两极上面肯定没有水,我们从里面两个点来算。
当左边最大值小于右边时,我们移动左指针,反之则是右指针。

#include<stdio.h>
#include<iostream>
#include<vector>
using namespace std;
int main(){
    int n;
    cin>>n;
    vector<long long>arr(n);
    for(int i=0;i<n;i++){
        cin>>arr[i];
    }
    int L=1,R=n-2;
    long long water=0;
    long long Lmax=arr[0],Rmax=arr[n-1];
    while(L<=R){
        if(Lmax<=Rmax){
            if(Lmax-arr[L]>0)water+=Lmax-arr[L];
            Lmax=max(Lmax,arr[L]);
            //water+=max(0,(Lmax-arr[L]));
            L++;
        }
        else{
            if(Rmax-arr[R]>0)water+=Rmax-arr[R];
            Rmax=max(Rmax,arr[R]);
            //water+=max(0,(Rmax-arr[R]));
            R--;
        }
    }
    cout<<water<<endl;
}

牛客上有坑,int会超数字限制,我直接用long long了。。

二维情况是一维的进阶,我们先从外围边框着手,用到一个辅助的东西:堆,也就是优先队列。
priority_queue<Type, Container, Functional>

其中, Type 为数据类型. Container 为保存数据的容器. Functional 为元素比较的方式.

其中functional这部分用了一个class加重载。。
取一个小根堆,这样每次都能把最小的(瓶颈问题)给弄出来,然后把和它靠近的数字放入堆中,这一步计算该点水的量即最小瓶颈和该点位置的差。
循环往复。
这里用一个结构体来方便定义:

struct node{
    int val;
    int row;
    int col;
    node(int val,int row,int col):val(val),row(row),col(col){
        
    }
};

之后用的functional也用了这个:

class compare{
    public:
    bool operator()(node node1,node node2){
        return node1.val>node2.val;
    }
};

完整代码:

#include<bits/stdc++.h>
using namespace std;
struct node{
    int val;
    int row;
    int col;
    node(int val,int row,int col):val(val),row(row),col(col){
        
    }
};
int X[4]={-1,1,0,0};
int Y[4]={0,0,-1,1};
class compare{
    public:
    bool operator()(node node1,node node2){
        return node1.val>node2.val;
    }
};
int main(){
    int M,N;
    cin>>M>>N;
    vector<vector<int>>heightmap(M,vector<int>(N));
    for(int i=0;i<M;i++){
        for(int j=0;j<N;j++){
            cin>>heightmap[i][j];
        }
    }
    bool visitmap[140][140];//为啥100的100会有用例错啊
    //bool visitmap[M][N];//这个也不行..
    priority_queue<node,vector<node>,compare>heap;
    for(int i=0;i<M;i++){
        heap.push(node(heightmap[i][0],i,0));
        heap.push(node(heightmap[i][N-1],i,N-1));
        visitmap[i][0]=true;
        visitmap[i][N-1]=true;
    }
    for(int j=0;j<N;j++){
        heap.push(node(heightmap[0][j],0,j));
        heap.push(node(heightmap[M-1][j],M-1,j));
        visitmap[0][j]=true;
        visitmap[M-1][j]=true;
    }
    int most=0,water=0;
    int x,y;
    while(!heap.empty()){
        node res=heap.top();
        heap.pop();
        most=max(most,res.val);
        for(int i=0;i<4;i++){
            x=res.row+X[i];
            y=res.col+Y[i];
            if(x>=0&&y>=0&&x<M&&y<N&&!visitmap[x][y]){
                heap.push(node(heightmap[x][y],x,y));
                water+=max(0,most-heightmap[x][y]);
                visitmap[x][y]=true;
            }
        }
    }
    cout<<water<<endl;
}
举报

相关推荐

0 条评论