zoukankan      html  css  js  c++  java
  • Gym

    题目传送门

    题目大意:给出一幅海洋的描述,0为海平面,负数即有水,在给出的xy坐标的底部安放抽水机,问最多能有多少水。水往低处流,且八个方向都可以。

    思路:bfs,记录到每一个节点有效的最低海平面,然后尝试更新周围的点。

    但这道题需要优先队列,有效海平面最低的先出队,否则会TLE。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<string.h>
    #include<sstream>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<bitset>
    #define CLR(a,b) memset((a),(b),sizeof((a))) 
    using namespace std;
    typedef long long ll;
    inline int rd() {
        int f = 1; int x = 0; char s = getchar();
        while (s<'0' || s>'9') { if (s == '-')f = -1; s = getchar(); }
        while (s >= '0'&&s <= '9') { x = x * 10 + s - '0'; s = getchar(); }x *= f;
        return x;
    }
    const int maxn = 510;
    ll mp[maxn][maxn],mmp[maxn][maxn],vis[maxn][maxn];
    int n, m, x, y;
    int fx[8][2] = { {-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0} };
    struct dian {
        int x, y;
        ll low;
        inline dian(){}
        inline dian(int x,int y,ll low):x(x),y(y),low(low){}
        inline friend bool operator <(const dian & a, const dian &b) {
            return a.low > b.low;
        }
    };
    inline bool check(dian &s)
    {
        if (s.x <= 0 || s.y <= 0 || s.x > n || s.y > m||vis[s.x][s.y])return false;
        if (mp[s.x][s.y] > 0)return false;
        return true;
    }
    priority_queue<dian >q;
    int main() {
        scanf("%d%d", &n, &m);
            for (int i = 1; i <= n; i++)
            {
                for (int j = 1; j <= m; j++)
                {
                    scanf("%I64d", &mp[i][j]);
                }
        }
            scanf("%d%d", &x, &y);
            if (mp[x][y] > 0) {
                printf("0
    ");
                return 0;
            }
            q.push(dian(x, y,mp[x][y]));
            ll ans =0;
            mmp[x][y] = mp[x][y];
            vis[x][y] = 1;
            while (!q. empty()) {
                dian st = q.top();
                q.pop();
                for (int i = 0; i < 8; i++)
                {
                    dian now = st;
                    now.x += fx[i][0], now.y += fx[i][1];
                    if (!check(now))continue;
                    now.low= -min(-st.low, -mp[now.x][now.y]);
                    if (now.low < mmp[now.x][now.y]) {
                        q.push(now);
                        mmp[now.x][now.y] = now.low;
                        vis[now.x][now.y] = 1;
                    }
                }
            }
            for (int i = 1; i <= n; i++)
            {
                for (int j = 1; j <= m; j++)
                {
                    ans -= mmp[i][j];
                }
            }
            printf("%I64d
    ", ans);
    
    }
  • 相关阅读:
    电脑开机时一直滴滴的响开不了机是为什么?
    电脑开机时一直滴滴的响开不了机是为什么?
    winform窗体应用实现淡入淡出等效果
    winform窗体应用实现淡入淡出等效果
    windows-如何生成转储(dmp)文件--工具篇
    面向对象(三)- Java类的方法
    面向对象 (二)- Java类的属性
    面向对象 (二)- Java类的属性
    面向对象 (一)- Java中的类和对象
    面向对象 (一)- Java中的类和对象
  • 原文地址:https://www.cnblogs.com/mountaink/p/9563905.html
Copyright © 2011-2022 走看看