Cod sursa(job #3182808)

Utilizator PetraPetra Hedesiu Petra Data 9 decembrie 2023 17:21:31
Problema Barbar Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.34 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>
#include <cstring>

using namespace std;

ifstream fin ("barbar.in");
ofstream fout ("barbar.out");


struct q_entry {
    int i, j, dist;
};
struct q_entry2 {
    int i, j, val, dist;
};
struct poz {
    int i, j;
};

bool operator< (q_entry2 a, q_entry2 b)
{
    if (a.val == b.val) return a.dist > b.dist;
    return a.val < b.val;
}

int r, c, a[1003][1003], val[1003][1003], viz[1003][1003], is, js, iexit, jexit,
d[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}, mn = 0x3f;
priority_queue<q_entry2> pq;
queue<q_entry> q;
vector<poz> drg;

int on_map(int i, int j)
{
    return (1 <= i && i <= r && 1 <= j && j <= c);
}
void lee(int istart, int jstart)
{
    memset(viz, 0, sizeof(viz));
    val[istart][jstart] = 0;
    for (int i = 0; i < 4; i++)
        q.push({istart + d[i][0], jstart + d[i][1], 1});

    while (!q.empty())
    {
        q_entry c = q.front();
        q.pop();

        if (!on_map(c.i, c.j)) continue;
        if (a[c.i][c.j] == 1)
        {
            val[c.i][c.j] = -1;
            continue;
        }
        if (a[c.i][c.j] == 2) continue;
        if (viz[c.i][c.j]) continue;

        viz[c.i][c.j] = 1;
        if (val[c.i][c.j] > c.dist)
        {
            val[c.i][c.j] = c.dist;
            for (int i = 0; i < 4; i++)
            {
                q.push({c.i + d[i][0], c.j + d[i][1], c.dist + 1});
            }
        }
    }
}
void afis()
{
    for (int i = 1; i <= r; i++)
    {
        for (int j = 1; j <= c; j++)
            cout << viz[i][j] << " ";
        cout << "\n";
    }
    cout << endl;
    for (int i = 1; i <= r; i++)
    {
        for (int j = 1; j <= c; j++)
            cout << val[i][j]<< " ";
        cout << endl;
    }
}
void dijkstra(int istart, int jstart)
{
    memset(viz, 0, sizeof(viz));
    pq.push({istart, jstart, val[istart][jstart], 0});

    while(!pq.empty())
    {
        q_entry2 c = pq.top();
        pq.pop();

        if (viz[c.i][c.j]) continue;
        viz[c.i][c.j] = c.dist + 1;
        cout << mn << " ";
        mn = min(mn, c.val);

        if (c.i == iexit && c.j == jexit) return;
//        system("cls");
//        afis();
//        system("pause");


        for (int i = 0; i < 4; i++)
        {
            int ii = c.i + d[i][0], jj = c.j + d[i][1];
            if (!on_map(ii, jj)) continue;
            if (a[ii][jj] != 0) continue;
            if (viz[ii][jj]) continue;

            pq.push({ii, jj, val[ii][jj], c.dist + 1});
        }
    }
}

int main()
{
    fin >> r >> c;
    memset(val, 0x3f, sizeof(val));
    for (int i = 1; i <= r; i++)
    {
        for (int j = 1; j <= c; j++)
        {
            char c;
            fin >> c;
            if (c=='D') a[i][j] = 2;
            else if (c=='*') a[i][j] = 1;
            else
            {
                a[i][j] = 0;
                if (c=='O')
                {
                    iexit = i; jexit = j;
                }
                if (c=='I')
                {
                    is = i; js = j;
                }

            }
        }
    }
    for (int i = 1; i <= r; i++)
        for (int j = 1; j <= c; j++)
            if (a[i][j] == 2) lee(i, j);

    dijkstra(is, js);

    fout << mn;
    return 0;
}