Cod sursa(job #1216986)

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

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

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;
    }
}

bool check(int dis){
    int start=1,i,aux,x,y;
    K=1;
    q[1][0]=sx; q[1][1]=sy;

    if (!validDist(q[1][0],q[1][1],dis))
        return 0;

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

            if (q[i][0]==fx && q[i][1]==fy)
                return 1;

            if (validDist(x+1,y,dis)) add_cell(x+1,y);
            if (validDist(x-1,y,dis)) add_cell(x-1,y);
            if (validDist(x,y+1,dis)) add_cell(x,y+1);
            if (validDist(x,y-1,dis)) add_cell(x,y-1);

        }
        start=aux+1;
    }


    return 0;
}
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;
        if (check(mid)) l=mid;
        else r=mid-1;
    }
    memset(vizitat,0,sizeof(vizitat));
    if (check(l+1)) l++;

    out << l ;
    return 0;
}