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