Cod sursa(job #1216989)

Utilizator MaarcellKurt Godel Maarcell Data 6 august 2014 11:54:50
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.31 kb
#include <fstream>
#include <stdio.h>
#include <string.h>
using namespace std;

int N,M,K,res,dis, q[1010*1010][2], dist[1010][1010], a[1010][1010], sx,sy, fx,fy;
bool vizitat[1010][1010],exists;

void add(int x, int y, int l){
    q[++K][0]=x;
    q[K][1]=y;
    dist[x][y]=l;
}

void add_cell(int x, int y){
    q[++K][0]=x;
    q[K][1]=y;
}

bool valid(int x, int y){
    if (x<1 || x>N || y<1 || y>M || dist[x][y]!=0 || a[x][y]!=0 )
        return 0;
    return 1;
}

bool validDist(int x, int y, int k){
    if (x<1 || x>N || y<1 || y>M || dist[x][y]<k || a[x][y]!=0 || vizitat[x][y]!=0)
        return 0;
    return 1;
}

void find_dist(void){
    int start=1,l=1,i,aux,x,y;

    while (start<=K){
        aux=K;
        for (i=start; i<=aux; i++){
            x=q[i][0]; y=q[i][1];

            if (valid(x+1,y)) add(x+1,y,l);
            if (valid(x-1,y)) add(x-1,y,l);
            if (valid(x,y+1)) add(x,y+1,l);
            if (valid(x,y-1)) add(x,y-1,l);
        }
        l++;
        start=aux+1;
    }
}

void check(int x, int y){
    if (validDist(x,y,dis)){
        vizitat[x][y]=1;
        if (x==fx && y==fy){
            exists=true;
            return;
        }
        check(x+1,y);
        check(x-1,y);
        check(x,y+1);
        check(x,y-1);
    }
}
int main(){
    ifstream in("barbar.in");
    ofstream out("barbar.out");
    in >> N >> M;

    int i,j; char c;
    K=0;
    for (i=1; i<=N; i++)
        for (j=1; j<=M; j++){
            in >> c;
            if (c=='.' || c=='I' || c=='O')
                a[i][j]=0;
            else
                a[i][j]=1;

            if (c=='D'){
                q[++K][0]=i;
                q[K][1]=j;

            }
            else if (c=='I'){
                sx=i; sy=j;
            }
            else if (c=='O'){
                fx=i; fy=j;
            }
        }

    find_dist();

    int l=0,r=N+M,mid;

    while (r-l>1){
        memset(vizitat,0,sizeof(vizitat));
        mid=(l+r)/2; dis=mid; exists=false;
        check(sx,sy);
        if (exists) l=mid;
        else r=mid-1;
    }
    memset(vizitat,0,sizeof(vizitat));
    dis=l+1; exists=false;
    check(sx,sy);
    if (exists) l++;

    if (l==0)
        out << -1;
    else
        out << l;

    return 0;
}