Cod sursa(job #1772708)

Utilizator moise_alexandruMoise Alexandru moise_alexandru Data 6 octombrie 2016 22:45:33
Problema Barbar Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.11 kb
#include <iostream>
#include <fstream>
#include <bitset>
#include <queue>
using namespace std;
ifstream in("barbar.in");
ofstream out("barbar.out");
const int inf = (1 << 30);
const int maxn = 1005;
int dist[maxn][maxn];
bitset <maxn> viz[maxn];
int M[maxn][maxn];
char linie[maxn];
int n, m, startx, starty, finx, finy;
queue <pair <int, int> > q;

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

inline bool inside(int x, int y)
{
    if(x >= 1 && x <= n && y >= 1 && y <= m && M[x][y] != -1) //&& !viz[x][y]
        return 1;
    return 0;
}

void citire_initializare()
{
    for(int i = 0; i < maxn; i++)
        for(int j = 0; j < maxn; j++)
            dist[i][j] = inf;
    for(int i = 1; i <= n; i++)
    {
        in.getline(linie + 1, maxn);
        for(int j = 1; j <= m; j++)
        {
            if(linie[j] == 'D')
            {
                q.push(make_pair(i, j));
                dist[i][j] = 0;
                M[i][j] = -1;
                //viz[i][j] = 1;
            }
            if(linie[j] == '*')
                M[i][j] = -1;
            if(linie[j] == 'I')
            {
                startx = i;
                starty = j;
            }
            if(linie[j] == 'O')
            {
                finx = i;
                finy = j;
            }
        }
    }
}

void bfs()
{
    while(!q.empty())
    {
        pair <int, int> p = q.front();
        q.pop();
        for(int i = 0; i < 4; i++)
        {
            int xnou = p.first + dx[i];
            int ynou = p.second + dy[i];
            if(inside(xnou, ynou) && dist[xnou][ynou] > dist[p.first][p.second] + 1)
            {
                dist[xnou][ynou] = dist[p.first][p.second] + 1;
                q.push(make_pair(xnou, ynou));
            }
        }
    }
}

bool ok;
int cost;
void _fill_(int x, int y)
{
    if(ok == 1)
        return;
    viz[x][y] = 1;
    if(x == finx && y == finy)
    {
        ok = 1;
        return;
    }
    for(int i = 0; i < 4; i++)
    {
        int xnou = x + dx[i];
        int ynou = y + dy[i];
        if(inside(xnou, ynou) && viz[xnou][ynou] == 0 && dist[xnou][ynou] >= cost)
            _fill_(xnou, ynou);
    }
}

bool verif(int x)
{
    ok = 0;
    cost = x;
    for(int i = 0; i < maxn; i++)
        for(int j = 0; j < maxn; j++)
            viz[i][j] = 0;
    _fill_(startx, starty);
    if(viz[finx][finy] == 1)
        return 1;
    return 0;
}


int cautbin()
{
    int st = 0;
    int dr = n * m;
    int rez = 0;
    while(st <= dr)
    {
        int mij = (st + dr) / 2;
        //cerr << verif(mij) << " ";
        if(verif(mij) == 1)
        {
            rez = mij;
            st = mij + 1;
        }
        else
            dr = mij - 1;
    }
    //cerr << "\n";
    return rez;
}

int main()
{
    in >> n >> m;
    in.getline(linie + 1, maxn);
    citire_initializare();
    bfs();
    //for(int i = 1; i <= n; i++, cerr << "\n")
        //for(int j = 1; j <= m; j++)
            //cerr << dist[i][j] << " ";
    out << cautbin() << "\n";
    return 0;
}