Cod sursa(job #688436)

Utilizator PetcuIoanPetcu Ioan Vlad PetcuIoan Data 23 februarie 2012 16:16:33
Problema Barbar Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.34 kb
#include<stdio.h>
#include<string.h>
#include<assert.h>

#include<algorithm>
#include<vector>

using namespace std;

struct place{
    int x, y;

    place(){};

    place(int x1, int y1){
        x = x1;
        y = y1;
    }
};

const int kdim = 1024;
char dungeon_map[kdim][kdim];
vector<place> queue;
int col, lin, xst, yst, xfin, yfin, sol = -1, dmap[kdim][kdim], map[kdim][kdim];

void read(){
    assert(freopen("barbar.in","r",stdin)!=NULL);
    int i, j;
    scanf("%d%d\n",&lin ,&col);
    for(i = 1; i <= lin; ++i){
        for(j = 1; j <= col; ++j)
            scanf("%c",&dungeon_map[i][j]);
        scanf("\n");
    }
}

bool vis[kdim][kdim];
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};

int is_drake_valid(int x, int y){
    if(x < 1 || y < 1 || x > lin || y > col)
        return 0;
    if(dmap[x][y])
        return 0;
    return 1;
}

int is_savage_valid(int x, int y){
    if(x < 1 || y < 1 || x > lin || y > col)
        return 0;
    if(map[x][y] == -1 || vis[x][y])
        return 0;
    return 1;
}

void bfs_drake(){
    int curent = 0, i;
    place aux;
    while(curent < queue.size()){
        for(i = 0; i <= 3; ++i)
            if(is_drake_valid(queue[curent].x + dx[i], queue[curent].y + dy[i])){
                aux.x = queue[curent].x + dx[i];
                aux.y = queue[curent].y + dy[i];
                dmap[aux.x][aux.y] = dmap[queue[curent].x][queue[curent].y] + 1;
                queue.push_back(aux);
            }
        ++curent;
    }
    queue.clear();
}

int bfs_savage(int val){
    int i, j;
    for(i = 1; i <= lin; ++i)
        for(j = 1; j <= col; ++j)
            vis[i][j] = false;
    place aux;
    aux.x = xst;
    aux.y = yst;
    queue.push_back(aux);
    vis[aux.x][aux.y] = true;
    int curent = 0;
    if(dmap[aux.x][aux.y])
        while(curent < queue.size()){
            for(i = 0; i <= 3; ++i){
                aux.x = queue[curent].x + dx[i];
                aux.y = queue[curent].y + dy[i];
                if(is_savage_valid(aux.x, aux.y))
                    if(dmap[aux.x][aux.y] > val){
                        vis[aux.x][aux.y] = true;
                        queue.push_back(aux);
                    }
            }
            ++curent;
        }
    queue.clear();
    if(vis[xfin][yfin])
        return 1;
    return 0;
}

void solve(){
    place aux;
    int i, j;
    for(i = 1; i <= lin; ++i)
        for(j = 1; j <= col; ++j)
            if(dungeon_map[i][j] == '.');
            else if(dungeon_map[i][j] == '*')
                map[i][j] = -1;
            else if(dungeon_map[i][j] == 'D'){
                dmap[i][j] = 1;
                map[i][j] = -1;
                aux.x = i;
                aux.y = j;
                queue.push_back(aux);
            }
            else if(dungeon_map[i][j] == 'I'){
                xst = i;
                yst = j;
            }
            else if(dungeon_map[i][j] == 'O'){
                xfin = i;
                yfin = j;
            }
    bfs_drake();
    int left = 1, right = 2003, mid, last = -1;
    while(left <= right){
        mid = (left + right) / 2;
        if(bfs_savage(mid)){
            left = mid + 1;
            last = mid;
        }
        else
            right = mid - 1;
    }
    sol = last;
}

void write(){
    assert(freopen("barbar.out","w",stdout)!=NULL);
    printf("%d",sol);
}

int main(){
    read();
    solve();
    write();
    return 0;
}