Cod sursa(job #1329805)

Utilizator mihail.jianuJianu Mihail mihail.jianu Data 29 ianuarie 2015 21:14:04
Problema Barbar Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.05 kb
#include<cstdio>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
const int N=1010;
const int LIN[]={-1,0,1,0};
const int COL[]={0,1,0,-1};
class Node{
    public:
        int l,c;
        Node(){
        }
        Node(int ll,int cc){
            l=ll;
            c=cc;
        }
        bool operator==(const Node&nod)const{
            return l==nod.l&&c==nod.c;
        }
};
vector<Node>g[N+1];
queue<Node>q;
Node st,fn;
Node dragons[N*N+1];
int a[N+1][N+1];
int minn[N+1][N+1];
bool vis[N*N+1];
int din[N+1][N+1];
bool viz[N+1][N+1];
int n,m,d;
int t(Node nod){
    return (nod.l-1)*m+nod.c;
}
int t(int i,int j){
    return (i-1)*m+j;
}
void bfs(){
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=d;i++){
        q.push(dragons[i]);
        vis[t(dragons[i])]=true;
    }
    while(!q.empty()){
        Node dadd=q.front();
        int dad=t(dadd);
        for(unsigned int i=0;i<g[dad].size();i++){
            Node son=g[dad][i];
            if(!vis[t(son)]){
                q.push(son);
                vis[t(son)]=true;
                minn[son.l][son.c]=minn[dadd.l][dadd.c]+1;
            }
        }
        q.pop();
    }
}
bool ok(int sor,Node nod){
    if(viz[nod.l][nod.c])
        return false;
    viz[nod.l][nod.c]=true;
    if(sor==3)
        sor=3;
    if(din[nod.l][nod.c])
        return din[nod.l][nod.c];
    if(minn[nod.l][nod.c]<sor){
        din[nod.l][nod.c]=1;
        return false;
    }
    if(nod==fn){
        din[nod.l][nod.c]=2;
        return true;
    }
    bool f=false;
    for(int dir=0;dir<=3;dir++)
        if(a[nod.l+LIN[dir]][nod.c+COL[dir]]==0)
            f=f||ok(sor,Node(nod.l+LIN[dir],nod.c+COL[dir]));
    din[nod.l][nod.c]=f+1;
    return f;
}
void bsearch(){
    int p=1<<20;
    int pos=0,r=-1;
    while(p){
        for(int i=1;i<=n;i++){
            memset(din[i],0,sizeof(din[i]));
            memset(viz,0,sizeof(viz));
        }
        if(ok(pos+p,st)){
            pos+=p;
            r=pos;
        }
        p/=2;
    }
    if(r==-1)
        if(ok(0,st))
            printf("0");
        else
            printf("-1");
    else
        printf("%d",r);
}
int main(){
    freopen("barbar.in","r",stdin);
    freopen("barbar.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("\n");
        for(int j=1;j<=m;j++){
            char c;
            scanf("%c",&c);
            if(c=='*')
                a[i][j]=1;
            else if(c=='D')
                dragons[++d]=Node(i,j);
            else if(c=='I')
                st=Node(i,j);
            else
                fn=Node(i,j);
        }
    }
    for(int i=0;i<=n+1;i++)
        a[i][0]=a[i][m+1]=1;
    for(int i=0;i<=m+1;i++)
        a[0][i]=a[n+1][i]=1;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            for(int dir=0;dir<=3;dir++)
                if(a[i+LIN[dir]][j+COL[dir]]==0)
                    g[t(i,j)].push_back(Node(i+LIN[dir],j+COL[dir]));
    bfs();
    bsearch();
    return 0;
}