Cod sursa(job #2078489)

Utilizator xkz01X.K.Z. xkz01 Data 29 noiembrie 2017 17:18:25
Problema Barbar Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.25 kb
#include<cstdio>
#include<deque>
#include<utility>
using namespace std;
const int dx[4]={-1, 0, 1, 0};
const int dy[4]={0, 1, 0, -1};
int i, j, n, m, x, y, x1, x2, y1, y2, k, mat[1002][1002], test_mat[1002][1002], max_mat;
deque<pair<int,int> > cd;
void citire(){
    char s[1002];
    scanf("%d %d\n", &n, &m);
    for (i=1;i<=n;i++) {
        gets(s);
        for (j=0;j<m;j++) {
            if (s[j]=='.') mat[i][j+1]=n*m+1;
            if (s[j]=='*') mat[i][j+1]=-1;
            if (s[j]=='D') {mat[i][j+1]=0; cd.push_back(make_pair(i, j+1));}
            if (s[j]=='I') {mat[i][j+1]=n*m+1; x1=i; y1=j+1;}
            if (s[j]=='O') {mat[i][j+1]=n*m+1; x2=i; y2=j+1;}
        }
    }
    for (i=1;i<=n;i++) {mat[i][0]=-1; mat[i][m+1]=-1;}
    for (j=1;j<=m;j++) {mat[0][j]=-1; mat[n+1][j]=-1;}
}
void expandare(){
    max_mat=0;
    while (!cd.empty()) {
        x=(cd.front()).first; y=(cd.front()).second; cd.pop_front();
        for (k=0;k<=3;k++)
            if (mat[x+dx[k]][y+dy[k]]>mat[x][y]) {
                mat[x+dx[k]][y+dy[k]]=mat[x][y]+1;
                if (mat[x][y]+1>max_mat) max_mat=mat[x][y]+1;
                cd.push_back(make_pair(x+dx[k], y+dy[k]));
            }
    }
    ///fara cd.clear() ca e deja goala
}
bool posibil(int dist_min){
    ///cd.clear() doar daca returneaza true
    cd.push_back(make_pair(x1, y1));
    for (i=0;i<=n+1;i++) for (j=0;j<=m+1;j++) test_mat[i][j]=mat[i][j];
    test_mat[x][y]=-1;
    while (!cd.empty()) {
        x=(cd.front()).first; y=(cd.front()).second; cd.pop_front();
        for (k=0;k<=3;k++)
            if (test_mat[x+dx[k]][y+dy[k]]>=dist_min) {
                if ((x+dx[k]==x2)&&(y+dy[k]==y2)) {cd.clear(); return true;}
                cd.push_back(make_pair(x+dx[k], y+dy[k]));
                test_mat[x+dx[k]][y+dy[k]]=-1;
            }
    }
    return false;
}
int solve(){
    int st=1, dr=max_mat, mij, sol=0;
    while (st<dr) {
        mij=st+(dr-st)/2;
        if (posibil(mij)) {sol=mij; st=mij+1;}
            else dr=mij-1;
    }
    return sol;
}
int main(){
    freopen("barbar.in","r",stdin);
    freopen("barbar.out","w",stdout);
    citire();
    expandare();
    int rezultat=solve();
    printf("%d\n", rezultat);
    return 0;
}