Cod sursa(job #1454595)

Utilizator preda.andreiPreda Andrei preda.andrei Data 27 iunie 2015 00:18:53
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.02 kb
#include <iostream>
#include <fstream>

using namespace std;

const int modLin[4]={-1, 0, 1, 0};
const int modCol[4]={0, 1, 0, -1};
bool mat[1001][1001];
bool v[1001][1001];
int dist[1001][1001];
int x[1000001];
int y[1000001];

void citireDate(int &n, int &m, int &dragoni, int &xi, int &yi, int &xs, int &ys)
{
    ifstream fin("barbar.in");
    char ch;

    fin >> n >> m;
    dragoni=0;
    for(int i=1; i<=n; i++){
        for(int j=1; j<=m; j++){
            fin >> ch;
            if(ch=='D'){
                dragoni++;
                x[dragoni]=i;
                y[dragoni]=j;
                dist[i][j]=-1;
            }
            else if(ch=='I'){
                xi=i;
                yi=j;
            }
            else if(ch=='O'){
                xs=i;
                ys=j;
            }
            else if(ch=='*'){
                v[i][j]=mat[i][j]=true;
                dist[i][j]=-1;
            }
        }
    }
}

void expansiuneDragoni(int k, int n, int m, int &dmax)
{
    int con=1, cx, cy, val;
    dmax=0;
    while(con<=k){
        val=dist[x[con]][y[con]]+1;
        if(val==0)
            val=1;
        for(int i=0; i<4; i++){
            cx=x[con]+modLin[i];
            cy=y[con]+modCol[i];
            if(cx>=1 && cx<=n && cy>=1 && cy<=m && dist[cx][cy]!=-1 && (dist[cx][cy]>val || dist[cx][cy]==0)){
                k++;
                x[k]=cx;
                y[k]=cy;
                dist[cx][cy]=val;
                if(val>dmax)
                    dmax=val;
            }
        }
        con++;
    }
}

void expansiune(int cx, int cy, int m, int n, int &k, int valMin)
{
    int x1, y1;
    for(int i=0; i<4; i++){
        x1=cx+modLin[i];
        y1=cy+modCol[i];
        if(x1>=1 && x1<=n && y1>=1 && y1<=m && !v[x1][y1] && dist[x1][y1]>=valMin){
            k++;
            x[k]=x1;
            y[k]=y1;
            v[x1][y1]=true;
        }
    }
}

bool lee(int n, int m, int xi, int yi, int xs, int ys, int valMin)
{
    bool valid;
    if(dist[xi][yi]<valMin)
        return false;
    int con, k, cx, cy;
    x[1]=xi;
    y[1]=yi;
    con=k=1;
    v[xs][ys]=false;
    v[xi][yi]=true;
    while(v[xs][ys]==false && con<=k){
        cx=x[con];
        cy=y[con];
        expansiune(cx, cy, m, n, k, valMin);
        con++;
    }
    valid=v[xs][ys];

    for(int i=1; i<=n; i++){
        for(int j=1; j<=m; j++){
            v[i][j]=mat[i][j];
        }
    }

    return valid;
}

int main()
{
    ofstream fout("barbar.out");

    int n, m, dragoni, xi, yi, xs, ys, distanta=-1, st, dr, mij, dmax;
    citireDate(n, m, dragoni, xi, yi, xs, ys);
    expansiuneDragoni(dragoni, n, m, dmax);
    for(int i=1; i<=dragoni; i++)
        dist[x[i]][y[i]]=0;

    st=0;
    dr=dmax;
    while(st<=dr){
        mij=(st+dr)/2;
        if(lee(n, m, xi, yi, xs, ys, mij)){
            distanta=mij;
            st=mij+1;
        }
        else
            dr=mij-1;
    }
    fout << distanta;
    return 0;
}