Submission #1162162

#TimeUsernameProblemLanguageResultExecution timeMemory
1162162minhpkJakarta Skyscrapers (APIO15_skyscraper)C++20
57 / 100
1097 ms52864 KiB
#include <bits/stdc++.h>

using namespace std;

int a, b;
vector<int> z[1000005];
int blocksize;
pair<int, int> mark[30005];

struct node {
    int val, pos, type;
    bool operator>(const node &other) const {
        return val > other.val;
    }
};

map<pair<int, int>, int> cnt;

void dijkstra() {
    priority_queue<node, vector<node>, greater<node>> q;
    q.push({0, mark[0].first, mark[0].second});
    cnt[{mark[0].first, mark[0].second}] = 0;

    while (!q.empty()) {
        node pos = q.top();
        q.pop();
        int val = pos.val;
        int pos1 = pos.pos;
        int type = pos.type;

        if (cnt[{pos1, type}] < val) continue;

        if (type == 0) {
            for (auto p : z[pos1]) {
                if (p + pos1 < a) {
                    if (!cnt.count({p + pos1, p}) || cnt[{p + pos1, p}] > val + 1) {
                        cnt[{p + pos1, p}] = val + 1;
                        q.push({cnt[{p + pos1, p}], p + pos1, p});
                    }
                }

                if (pos1 - p >= 0) {
                    if (!cnt.count({pos1 - p, p}) || cnt[{pos1 - p, p}] > val + 1) {
                        cnt[{pos1 - p, p}] = val + 1;
                        q.push({cnt[{pos1 - p, p}], pos1 - p, p});
                    }
                }
            }
        } else {
            if (!cnt.count({pos1, 0}) || cnt[{pos1, 0}] > val) {
                cnt[{pos1, 0}] = val;
                q.push({val, pos1, 0});
            }

            if (type > blocksize) {
                int cnt1 = 1;
                while (pos1 + cnt1 * type < a) {
                    int nxt = pos1 + cnt1 * type;
                    if (!cnt.count({nxt, 0}) || cnt[{nxt, 0}] > val + cnt1) {
                        cnt[{nxt, 0}] = val + cnt1;
                        q.push({cnt[{nxt, 0}], nxt, 0});
                    }
                    cnt1++;
                }

                cnt1 = 1;
                while (pos1 - cnt1 * type >= 0) {
                    int nxt = pos1 - cnt1 * type;
                    if (!cnt.count({nxt, 0}) || cnt[{nxt, 0}] > val + cnt1) {
                        cnt[{nxt, 0}] = val + cnt1;
                        q.push({cnt[{nxt, 0}], nxt, 0});
                    }
                    cnt1++;
                }
            } else {
                int nxt1 = pos1 + type;
                int nxt2 = pos1 - type;

                if (nxt1 < a && (!cnt.count({nxt1, type}) || cnt[{nxt1, type}] > val + 1)) {
                    cnt[{nxt1, type}] = val + 1;
                    q.push({cnt[{nxt1, type}], nxt1, type});
                }

                if (nxt2 >= 0 && (!cnt.count({nxt2, type}) || cnt[{nxt2, type}] > val + 1)) {
                    cnt[{nxt2, type}] = val + 1;
                    q.push({cnt[{nxt2, type}], nxt2, type});
                }
            }
        }
    }
}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> a >> b;
    blocksize = sqrt(a);

    for (int i = 0; i < b; i++) {
        int x, y;
        cin >> x >> y;
        z[x].push_back(y);
        mark[i] = {x, y};
    }

    if (b == 0) {
        cout << -1;
        return 0;
    }

    dijkstra();

    if (cnt.count({mark[1].first, 0})) {
        cout << cnt[{mark[1].first, 0}];
    } else {
        cout << -1;
    }

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...