Cod sursa(job #1499782)

Utilizator moise_alexandruMoise Alexandru moise_alexandru Data 11 octombrie 2015 09:56:54
Problema Barbar Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.77 kb
#include <iostream>
#include <fstream>
#include <bitset>
#include <queue>
#include <cassert>
using namespace std;
ifstream in("barbar.in");
ofstream out("barbar.out");

const int maxn = 1005;
int M[maxn][maxn];
bitset <maxn> viz[maxn];
char T[maxn];
queue <pair <int, int> > dragon;
const int dx[] = {-1, 0, 1, 0};
const int dy[] = { 0, 1, 0,-1};
int n, m;
pair <int, int> start;
pair <int, int> fin;

inline bool inside(int x, int y)
{
    if(x >= 1 && y >= 1 && x <= n && y <= m)
        return 1;
    return 0;
}

void lee_dragoni()
{
    while(!dragon.empty())
    {
        pair <int, int> p = dragon.front();
        dragon.pop();
        int x = p.first;
        int y = p.second;
        for(int i = 0; i < 4; i++)
        {
            int xnou = x + dx[i];
            int ynou = y + dy[i];
            if(M[xnou][ynou] == -2 && inside(xnou, ynou)) { /// nevizitata, si libera
                M[xnou][ynou] = M[x][y] + 1;
                dragon.push(make_pair(xnou, ynou));
            }
        }
    }
}


queue <pair<int, int>> q;

void _lee(int xst, int yst, int dmax) {
    viz[xst][yst] = 1;
    while(!q.empty())
        q.pop();
    q.push(make_pair(xst, yst));
    while(!q.empty()) {
        int x = q.front().first;
        int y = q.front().second;
        q.pop();
        for(int d = 0 ; d < 4 ; ++ d) {
            int xnou = x + dx[d];
            int ynou = y + dy[d];
            if(inside(xnou, ynou) && viz[xnou][ynou] == 0 && M[xnou][ynou] >= dmax) {
                viz[xnou][ynou] = 1;
                q.push(make_pair(xnou, ynou));
                if(xnou == fin.first && ynou == fin.second)
                    return ;
            }
        }
    }
}

int main()
{
    in >> n >> m;
    for(int i = 1; i<=n; i++)
    {
        in.getline(T+1, maxn);
        for(int j = 1; j <= m; j++)
        {
            M[i][j] = -2; /// pozitie libera, nevizitata
            if(T[j] == 'D')
            {
                dragon.push(make_pair(i, j));
                M[i][j] = 0;
            }
            if(T[j] == 'O')
                fin = make_pair(i, j);
            if(T[j] == 'I')
                start = make_pair(i, j);
            if(T[j] == '*')
                M[i][j] = -1;
        }
    }

    lee_dragoni();

    int st = 1;
    int dr = n + m - 1;
    int ret = -1;
    while(st <= dr)
    {
        int mij = (st + dr) / 2;
        for(int i = 1 ; i <= n ; ++ i)
            viz[i].reset();
        if(M[start.first][start.second] >= mij)
            _lee(start.first, start.second, mij);
        if(viz[fin.first][fin.second] == 1)
        {
            ret = mij;
            st = mij + 1;
        }
        else
            dr = mij - 1;
    }
    out << ret;
    return 0;
}