Submission #379594

#TimeUsernameProblemLanguageResultExecution timeMemory
379594KubinPortals (BOI14_portals)C++17
20 / 100
9 ms4480 KiB
#include <bits/stdc++.h>

using namespace std;

const size_t N = 1024;

template<typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;

int main()
{
    ios::sync_with_stdio(false); cin.tie(nullptr);

    size_t h, w;
    cin >> h >> w;

    static array<array<bool, N>, N> lock = {};
    size_t sy = 0, sx = 0, fy = 0, fx = 0;

    for(size_t y = 0; y <= h+1; y++)
        for(size_t x = 0; x <= w+1; x++)
            lock[y][x] = true;
    for(size_t y = 1; y <= h; y++)
    {
        string row;
        cin >> row;
        for(size_t x = 1; x <= w; x++)
        {
            auto c = row[x-1];
            lock[y][x] = c == '#';
            if(c == 'S')
                sy = y, sx = x;
            if(c == 'C')
                fy = y, fx = x;
        }
    }

    queue<pair<size_t, size_t>> que;
    static array<array<int, N>, N> wall_dist = {};
    auto wall_maybe = [&](size_t y, size_t x, int d) {
        if(wall_dist[y][x] == int(w*h))
            wall_dist[y][x] = d, que.emplace(y, x);
    };
    for(size_t y = 0; y <= h+1; y++)
      for(size_t x = 0; x <= w+1; x++)
    {
        wall_dist[y][x] = w*h;
        if(lock[y][x])
            wall_maybe(y, x, 0);
    }

    while(not que.empty())
    {
        auto [y, x] = que.front(); que.pop();
        auto d = wall_dist[y][x] + 1;
        if(y) wall_maybe(y - 1, x, d);
        if(x) wall_maybe(y, x - 1, d);
        if(y<=h) wall_maybe(y + 1, x, d);
        if(x<=w) wall_maybe(y, x + 1, d);
    }

    /*
    for(size_t y = 0; y <= h+1; y++, cout << endl)
        for(size_t x = 0; x <= w+1; x++, cout << ' ')
            cout << wall_dist[y][x];
    */

    static array<array<array<size_t, 4>, N>, N> towards;
    constexpr size_t UP = 0, LEFT = 1, DOWN = 2, RIGHT = 3;
    for(size_t y = 0; y <= h+1; y++)
        for(size_t x = 0; x <= w+1; x++)
            towards[y][x].fill(SIZE_MAX);

    for(size_t y = 1; y <= h; y++)
        for(size_t x = 1; x <= w; x++)
            if(not lock[y][x])
                towards[y][x][UP] = towards[y-1][x][UP] == SIZE_MAX ? y : towards[y-1][x][UP],
                towards[y][x][LEFT] = towards[y][x-1][LEFT] == SIZE_MAX ? x : towards[y][x-1][LEFT];
    for(size_t y = h+1; y --> 1; )
        for(size_t x = w+1; x --> 1; )
            if(not lock[y][x])
                towards[y][x][DOWN] = towards[y+1][x][DOWN] == SIZE_MAX ? y : towards[y+1][x][DOWN],
                towards[y][x][RIGHT] = towards[y][x+1][RIGHT] == SIZE_MAX ? x : towards[y][x+1][RIGHT];
    /*
    cout << "UP" << endl;
    for(size_t y = 0; y <= h+1; y++, cout << endl)
        for(size_t x = 0; x <= w+1; x++, cout << ' ')
            cout << (towards[y][x][UP]==SIZE_MAX ? "#" : to_string(towards[y][x][UP]));
    cout << "LEFT" << endl;
    for(size_t y = 0; y <= h+1; y++, cout << endl)
        for(size_t x = 0; x <= w+1; x++, cout << ' ')
            cout << (towards[y][x][LEFT]==SIZE_MAX ? "#" : to_string(towards[y][x][LEFT]));
    cout << "DOWN" << endl;
    for(size_t y = 0; y <= h+1; y++, cout << endl)
        for(size_t x = 0; x <= w+1; x++, cout << ' ')
            cout << (towards[y][x][DOWN]==SIZE_MAX ? "#" : to_string(towards[y][x][DOWN]));
    cout << "RIGHT" << endl;
    for(size_t y = 0; y <= h+1; y++, cout << endl)
        for(size_t x = 0; x <= w+1; x++, cout << ' ')
            cout << (towards[y][x][RIGHT]==SIZE_MAX ? "#" : to_string(towards[y][x][RIGHT]));
    */

    static array<array<int, N>, N> dist = {};
    for(size_t y = 0; y <= h+1; y++)
        for(size_t x = 0; x <= w+1; x++)
            dist[y][x] = w*h + lock[y][x];

    min_heap<tuple<int, size_t, size_t>> heap;
    static array<array<bool, N>, N> vis = {};
    auto maybe = [&](size_t y, size_t x, int d) {
        if(dist[y][x] == int(w*h) and d < dist[y][x])
            heap.emplace(dist[y][x] = d, y, x);
    };
    maybe(sy, sx, 0);
    while(not heap.empty())
    {
        auto [_, y, x] = heap.top(); heap.pop();
        if(vis[y][x])
            continue;
        vis[y][x] = true;
        auto d = dist[y][x], c = wall_dist[y][x];
        maybe(y - 1, x, d + 1); maybe(y, x - 1, d + 1);
        maybe(y + 1, x, d + 1); maybe(y, x + 1, d + 1);
        maybe(towards[y][x][UP], x, d + c);
        maybe(towards[y][x][DOWN], x, d + c);
        maybe(y, towards[y][x][LEFT], d + c);
        maybe(y, towards[y][x][RIGHT], d + c);
    }
    /*
    for(size_t y = 0; y <= h+1; y++, cout << endl)
        for(size_t x = 0; x <= w+1; x++, cout << ' ')
            cout << (dist[y][x]>=w*h ? "#" : to_string(dist[y][x]));
    */

    cout << dist[fy][fx] << endl;
}
#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...