LintCode 364 Trapping Rain Water II

Given n * m non-negative integers representing an elevation map 2d where the area of each cell is 1 * 1, compute how much water it is able to trap after raining.


给出 n * m 个非负整数,代表一张X轴上每个区域为 1 * 1 的 2d 海拔图, 计算这个海拔图最多能接住多少(面积)雨水。



该题解题思路与现实生活完全一致,也就是水往地处流,因此可以通过最小堆及BFS搜索来求解该题。

首先对矩阵数据建堆,

然后从堆里面选取最小元素,进行BSF遍历,如果值相等,继续往下走,如果遇到比当前值小的,或者边境,说明该水流会流出去(遇到这种情况对遍历的数据置为-1)说明往后连通该区域的水都会流出去,如果BFS一遍发现没有到边界和遇到比起小的点,则将遍历过的点的值设为遇到的最小的点,并更新水的流量,继续进行遍历。直至所有点都为-1为止,输出结果


//

//  main.cpp

//  ContainWalter

//

//  Created by 孟文斌 on 15/4/28.

//  Copyright (c) 2015 孟文斌. All rights reserved.

//


#include <iostream>

#include <vector>

#include <queue>


using namespace std;


struct pos{

    int x;

    int y;

    int val;

    pos(){}

    pos(int a,int b,int c):x(a),y(b),val(c){}

    int compare(const void * a, const void *b){

        int *ta = (int *)a;

        int *tb = (int *)b;

        return (*ta - *tb);

    }

};


struct ValCmp{

    bool operator() (const pos &A,const pos &B){

        return A.val > B.val;

    }

};



class Solution {

private:

    void displayVector(vector<vector<int> > &heights){

        for(int i=0;i<m;i++){

            for(int j=0;j<n;j++){

                cout << heights[i][j]<<" ";

            }

            cout<<endl;

        }

    }

    int m,n;

    

    int visitPos(vector<vector<int>> &heights,pos p){

        queue<pos> q,t;

        pos tmp;

        bool avail = 1;

        q.push(p);

        heights[p.x][p.y] = -2;

        int x,y,v,minn=INT_MAX;

        while(!q.empty()){

            tmp = q.front();

            t.push(tmp);

            q.pop();

            x = tmp.x;y=tmp.y;

            if(x > 0){

                v = heights[x-1][y];

                if(v == -2){

                }else if(v < p.val){

                    avail = 0;

                }else if(v == p.val){

                    if(avail){

                        q.push(pos(x-1,y,v));

                        heights[x-1][y] = -2;

                    }else {

                        heights[x-1][y] = -1;

                    }

                }else {

                    if(avail) minn = min(minn,v);

                }

            }else {

                avail = 0;

            }

            

            if(x < m-1){

                v = heights[x+1][y];

                if(v == -2){

                }else if(v < p.val){

                    avail = 0;

                }else if(v == p.val){

                    if(avail){

                        q.push(pos(x+1,y,v));

                        heights[x+1][y] = -2;

                    }else {

                        heights[x+1][y] = -1;

                    }

                }else {

                    if(avail) minn = min(minn,v);

                }

            }else {

                avail = 0;

            }

            

            if(y > 0){

                v = heights[x][y-1];

                if(v == -2){

                }else if(v < p.val){

                    avail = 0;

                }else if(v == p.val){

                    if(avail){

                        q.push(pos(x,y-1,v));

                        heights[x][y-1] = -2;

                    }else {

                        heights[x][y-1] = -1;

                    }

                }else {

                    if(avail) minn = min(minn,v);

                }

            }else {

                avail = 0;

            }

            

            if(y < n-1){

                v = heights[x][y+1];

                if(v == -2){

                }else if(v < p.val){

                    avail = 0;

                }else if(v == p.val){

                    if(avail){

                        q.push(pos(x,y+1,v));

                        heights[x][y+1] = -2;

                    }else {

                        heights[x][y+1] = -1;

                    }

                }else {

                    if(avail) minn = min(minn,v);

                }

            }else {

                avail = 0;

            }

            

        }

        if(avail){

            int val = 0;

            while (!t.empty()) {

                tmp = t.front();

                t.pop();

                x = tmp.x;y=tmp.y;

                heights[x][y] = minn;

                val += minn-p.val;

            }

            return val;

        }

        while (!t.empty()) {

            tmp = t.front();

            t.pop();

            heights[tmp.x][tmp.y] = -1;

        }

        return 0;

    }

public:

    /**

     * @param heights: a matrix of integers

     * @return: an integer

     */

    int trapRainWater(vector<vector<int> > &heights) {

        // write your code here

        m = (int)heights.size();

        if(!m) return 0;

        n = (int)heights[0].size();

        priority_queue<pos,vector<pos,allocator<pos>>,ValCmp> hights_heap;

        for(int i=0;i<m;i++){

            for(int j=0;j<n;j++){

                hights_heap.push(pos(i,j,heights[i][j]));

            }

        }

        int val = 0,tv;

        while (!hights_heap.empty()) {

            pos p = hights_heap.top();

            hights_heap.pop();

            if(heights[p.x][p.y] != p.val) continue;//current point is visited before

            tv = visitPos(heights,p);

            if(tv){

                val += tv;

                p.val = heights[p.x][p.y];

                hights_heap.push(p);

            }

        }

        return val;

    }

};



int main(int argc, const char * argv[]) {

//    vector<vector<int> > heights = {{12,13,0,12},{13,4,13,12},{13,8,10,12},{12,13,12,12},{13,13,13,13}};

//    vector<vector<int> > heights = {{25,10,11,12,13},{24,9,2,3,14},{23,8,1,4,15},{22,7,6,5,16},{21,20,19,18,17}};

    vector<vector<int> > heights = {

        {25,10, 9,12,13},

        {24, 4, 5, 3,14},

        {23, 8, 3, 4,15},

        {22, 6, 9, 5,16},

        {21,20, 0,18,17}};

    Solution sol;

    cout<<sol.trapRainWater(heights)<<endl;

    return 0;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值