Submission #770694

#TimeUsernameProblemLanguageResultExecution timeMemory
770694boris_mihovMaze (JOI23_ho_t3)C++17
51 / 100
2099 ms347544 KiB
#include <algorithm>
#include <iostream>
#include <numeric>
#include <cassert>
#include <vector>
#include <queue>

typedef long long llong;
const int MAXN = 6000000 + 10;
const int INF  = 1e9;

int r, c, n;
int sRow, sCol;
int eRow, eCol;
std::pair <int,int> delta[] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
std::deque <std::pair <int,int>> dq;
std::vector <int> dist[MAXN];
std::string t[MAXN];

bool isOutside(int row, int col)
{
    return row == 0 || row == r + 1 || col == 0 || col == c + 1;
}

void solve()
{
    for (int i = 1 ; i <= r ; ++i)
    {
        std::fill(dist[i].begin(), dist[i].end(), INF);
    }
    
    dq.push_back({sRow, sCol});
    dist[sRow][sCol] = 0;

    while (!dq.empty())
    {
        auto [row, col] = dq.front();
        dq.pop_front();    

        if (row == eRow && col == eCol)
        {
            std::cout << dist[row][col] << '\n';
            break;
        }

        for (const auto &[dx, dy] : delta)
        {
            if (isOutside(row + dx, col + dy) || dist[row + dx][col + dy] <= dist[row][col])
            {
                continue;
            }

            if (t[row + dx][col + dy] == '.')
            {
                dist[row + dx][col + dy] = dist[row][col]; 
                dq.push_front({row + dx, col + dy});
            }
        }

        if (abs(row - eRow) <= n && abs(col - eCol) <= n && dist[eRow][eCol] > dist[row][col])
        {
            dist[eRow][eCol] = dist[row][col] + 1;
            dq.push_back({eRow, eCol});
        }

        for (int i = std::max(1, col - n + 1) ; i <= std::min(c, col + n - 1) ; ++i)
        {
            int prevR = std::max(1, row - n);
            int nextR = std::min(r, row + n);

            if (dist[prevR][i] > dist[row][col] + 1)
            {
                dist[prevR][i] = dist[row][col] + 1; 
                dq.push_back({prevR, i});
            }

            if (dist[nextR][i] > dist[row][col] + 1)
            {
                dist[nextR][i] = dist[row][col] + 1; 
                dq.push_back({nextR, i});
            }
        }

        for (int i = std::max(1, row - n + 1) ; i <= std::min(r, row + n - 1) ; ++i)
        {
            int prevC = std::max(1, col - n);
            int nextC = std::min(c, col + n);

            if (dist[i][prevC] > dist[row][col] + 1)
            {
                dist[i][prevC] = dist[row][col] + 1; 
                dq.push_back({i, prevC});
            }

            if (dist[i][nextC] > dist[row][col] + 1)
            {
                dist[i][nextC] = dist[row][col] + 1; 
                dq.push_back({i, nextC});
            }
        }
    }
}

void input()
{
    std::cin >> r >> c >> n;
    std::cin >> sRow >> sCol;
    std::cin >> eRow >> eCol;
    for (int i = 1 ; i <= r ; ++i)
    {
        std::cin >> t[i];
        t[i] = ' ' + t[i];
        dist[i].resize(c + 1, INF);
    }
}

void fastIOI()
{
    std::ios_base :: sync_with_stdio(0);
    std::cout.tie(nullptr);
    std::cin.tie(nullptr);
}

int main()
{
    fastIOI();
    input();
    solve();

    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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...