Cod sursa(job #798561)

Utilizator alexclpAlexandru Clapa alexclp Data 16 octombrie 2012 19:09:18
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.54 kb
#include <fstream>
#include <iostream>
#include <queue>

#define N 1005

using namespace std;

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

struct Pozitie {
    int x;
    int y;
};

queue <Pozitie> coada;

char map[N][N];
int drumDragoni[N][N];
int lee2[N][N];
int dirX[] = {-1, 0, 1, 0};
int dirY[] = {0, 1, 0, -1};
int n, m;
Pozitie start;
Pozitie final;

void bordare()
{
    for (int i = 0; i <= n+1; i++) {
        drumDragoni[i][0] = drumDragoni[i][m+1] = -1;
        lee2[i][0] = lee2[i][m+1] = -1;
    }
    for (int j = 0; j <= m+1; j++) {
        drumDragoni[0][j] = drumDragoni[n+1][j] = -1;
        lee2[0][j] = lee2[n+1][j] = -1;
    }
}


void leeDragoni()
{
    //coada.push(start);
    //drumDragoni[start.x][start.y] = 1;

    while (!coada.empty()) {
        Pozitie curent = coada.front();
        coada.pop();

        //cout << "\nscot " << curent.x << " " << curent.y << "\n\n";

        for (int i = 0; i < 4; i++) {
            int x = curent.x + dirX[i];
            int y = curent.y + dirY[i];

            if (drumDragoni[x][y] == 0) {
                drumDragoni[x][y] = drumDragoni[curent.x][curent.y] + 1;
                coada.push((Pozitie){x,y});
                //cout << "adaug " << x << " " << y << "\n";
                //if(x==0 || y==0)
                {
                    //return;
                }
            }
        }
    }

}

void clearLee()
{
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            lee2[i][j] = 0;
}

bool check(int pas)
{
    if (!drumDragoni[start.x][start.y] >= pas + 1) {
        return false;
    }

    clearLee();

    coada.push(start);
    lee2[start.x][start.y] = 1;


    while (!coada.empty()) {
        Pozitie curent = coada.front();
        coada.pop();

        for (int i = 0; i < 4; i++) {
            int x = curent.x + dirX[i];
            int y = curent.y + dirY[i];

            if (drumDragoni[x][y] >= pas+1 && lee2[x][y] == 0) {
                coada.push((Pozitie){x,y});
                lee2[x][y] = 1;
            }
        }
    }

    if (lee2[final.x][final.y] == 1) {
        return true;
    }
    return false;
}

void solve()
{
    int count;
    int pas = 1<<12;
    for (count = 0; pas; pas >>= 1) {
        if (check(count + pas) == true) {
            count += pas;
        }
    }
    if (count != 0) {
        out << count << "\n";
    } else {
        out << "-1";
    }
}


int main()
{
    in >> n >> m ;
    in.getline(map[0], 1);

    for (int i = 1; i <= n; i++) {
        in.getline(1 + map[i], N);
    }

    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (map[i][j] == 'I') {
                start.x = i;
                start.y = j;
                continue;
            }
            if (map[i][j] == '*') {
                drumDragoni[i][j] = -1;

                continue;
            }
            if (map[i][j] == 'O') {
                final.x = i;
                final.y = j;

                continue;
            }
            if (map[i][j] == 'D') {
                drumDragoni[i][j] = 1;
                coada.push((Pozitie){i,j});


                continue;
            }
        }
    }

    bordare();
    leeDragoni();
    solve();
    return 0;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
           cout << drumDragoni[i][j] << " ";
        }
        cout << "\n";
    }

    return 0;
}