Cod sursa(job #808505)

Utilizator NikitaUtiuNichita Utiu NikitaUtiu Data 6 noiembrie 2012 20:28:56
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.79 kb
#include <fstream>
#include <queue>
#include <algorithm>
using namespace std;

int n, m;
int cost[1001][1001];
bool visited[1001][1001];
char mat[1002][1002];
queue <pair <short, short> > coada;

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

int intrare_x, intrare_y, iesire_x, iesire_y;

inline bool ok(const int& x, const int& y) {
    return x >= 0 && x < n && y >= 0 && y < m;
}

bool lee(int minim) {
    while(!coada.empty()) coada.pop();
    for(int i = 0; i < n; ++i)
        for(int j = 0; j < m; ++j)
            visited[i][j] = false;
    
    coada.push(make_pair(intrare_x, intrare_y));
    visited[intrare_x][intrare_y] = true;
    
    while(!coada.empty()) {
        int i = coada.front().first, j = coada.front().second;
        coada.pop();
        for(int k = 0; k < 4; ++k) {
            int iv = i + dx[k], jv = j + dy[k];
            if(ok(iv, jv) && mat[iv][jv] != '*' && mat[iv][jv] != 'D' && !visited[iv][jv] && cost[iv][jv] >= minim) {
                if(iv == iesire_x && jv == iesire_y)
                    return true;
                visited[iv][jv] = true;
                coada.push(make_pair(iv, jv));
            }
        }
    }
    return false;
}
    

int main(void) {
    ifstream fin("barbar.in");
    fin >> n >> m; fin.get();
    for(int i = 0; i < n ; ++i)
        fin.getline(mat[i], 1002);
    fin.close();
    
    for(int i = 0; i < n ; ++i)
        for(int j = 0; j < m; ++j)
            cost[i][j] = 9999999;
    
    for(int i = 0; i < n; ++i)
        for(int j = 0; j < m; ++j) 
            if(mat[i][j] == 'D') {
                coada.push(make_pair(i, j));
                cost[i][j] = 0;
            }

    while(!coada.empty()) {
        int i = coada.front().first, j = coada.front().second;
        coada.pop();
        for(int k = 0; k < 4; ++k) {
            int iv = i + dx[k], jv = j + dy[k];
            if(ok(iv, jv) && mat[iv][jv] != '*' && mat[iv][jv] != 'D' && cost[iv][jv] > cost[i][j] + 1) {
                cost[iv][jv] = cost[i][j] + 1;
                coada.push(make_pair(iv, jv)); 
            }
        }
    }
    
    int cost_maxim = -1;
    for(int i = 0; i < n; ++i)
        for(int j = 0; j < m; ++j) {
            if(cost_maxim < cost[i][j] && cost[i][j] != 9999999)
                cost_maxim = cost[i][j];
            if(mat[i][j] == 'I')
                intrare_x = i, intrare_y = j;
            if(mat[i][j] == 'O')
                iesire_x = i, iesire_y = j;
        }
        
    cost_maxim = min(min(cost_maxim, cost[intrare_x][intrare_y]), cost[iesire_x][iesire_y]);
    int step, pos;   
    for(step = 1; step <= cost_maxim; step <<= 1);
    for(pos = -1; step != 0; step >>= 1) 
        if(pos + step <= cost_maxim && lee(pos + step))
            pos += step;
        
    ofstream fout("barbar.out");
    fout << pos << '\n';
    fout.close();
}