Cod sursa(job #3002297)

Utilizator PHOSSESSEDProsie Radu-Teodor PHOSSESSED Data 14 martie 2023 17:20:37
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.99 kb
#include<fstream>
#include<bitset>
#include<queue>
#include<vector>
using namespace std;

ifstream cin("barbar.in");
ofstream cout("barbar.out");

const int NMAX = 1e3 + 1;
const int dx[] = {1,-1,0,0};
const int dy[] = {0,0,-1,1};

bitset<NMAX> b[NMAX];
int dist[NMAX][NMAX],n,m;///dp[i][j] = distanta de la casuta i,j la cel mai apropiat dragon

bool inmat(const pair<int,int> &p)
{
    return (p.first >= 1 && p.first <= n && p.second >= 1 && p.second <= m);
}

bool putem(int vmax,pair<int,int> &start,pair<int,int> &finish)
{
    vector<vector<bool>> bad(n + 1,vector<bool>(m + 1,0));
    vector<vector<bool>> fost(n + 1,vector<bool>(m + 1,0));
    for(int i = 1; i <= n ; i++)
        for(int j = 1; j <= m ; j++)
            if(dist[i][j] < vmax || b[i][j]) bad[i][j] = 1;

    queue<pair<int,int>> q; q.push(start);
    if(bad[start.first][start.second]) return 0;
    fost[start.first][start.second] = 1;
    while(!q.empty())
        {
            pair<int,int> cell = q.front(); q.pop();
            for(int i = 0 ; i < 4; i++)
                {
                    pair<int,int> pun = cell;
                    pun.first += dx[i]; pun.second += dy[i];
                    if(inmat(pun) && !bad[pun.first][pun.second] && !fost[pun.first][pun.second])
                        {
                            fost[pun.first][pun.second] = 1;
                            q.push(pun);
                        }
                }
        }

    return fost[finish.first][finish.second];
}

int main()
{
    pair<int,int> start,finish;
    queue<pair<int,int>> dragoni;

    char read; cin >> n >> m;
    for(int i = 1; i <= n ; i++)
        {
            for(int j = 1; j <= m ; j++)
                {
                    cin >> read;
                    if(read == '.') continue;
                    if(read == '*') b[i][j] = 1;
                    else if(read == 'D')
                        {
                            dist[i][j] = 1;
                            dragoni.push({i,j});
                        }

                    else if(read == 'I') start = {i,j};
                    else finish = {i,j};

                }
        }

    while(!dragoni.empty())
        {
            pair<int,int> cell = dragoni.front(); dragoni.pop();
            for(int i = 0 ; i < 4 ; i++)
                {
                    pair<int,int> noua = cell;
                    noua.first += dx[i]; noua.second += dy[i];
                    if(inmat(noua) && !dist[noua.first][noua.second] && !b[noua.first][noua.second])
                        {
                            dist[noua.first][noua.second] = dist[cell.first][cell.second] + 1;
                            dragoni.push(noua);
                        }
                }
        }

    int ans = 0,pas = 1; while(pas < dist[start.first][start.second]) pas <<= 1;
    for(; pas ; pas >>= 1) if(putem(ans + pas,start,finish)) ans += pas;

    if(!putem(0,start,finish)) ans = 0;
    cout << ans - 1;
}