Cod sursa(job #1329869)

Utilizator mihail.jianuJianu Mihail mihail.jianu Data 29 ianuarie 2015 22:12:03
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.78 kb
#include<cstdio>
#include<queue>
#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;
        }
};
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];
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();
        for(int dir=0;dir<=3;dir++){
            Node son=Node(dadd.l+LIN[dir],dadd.c+COL[dir]);
            if(!vis[t(son)]&&a[son.l][son.c]==0){
                q.push(son);
                vis[t(son)]=true;
                minn[son.l][son.c]=minn[dadd.l][dadd.c]+1;
            }
        }
        q.pop();
    }
}
int sor;
bool ok(Node nod){
    while(!q.empty())
        q.pop();
    q.push(nod);
    while(!q.empty()){
        nod=q.front();
        if(nod==fn)
            return true;
        for(int dir=0;dir<=3;dir++)
            if(a[nod.l+LIN[dir]][nod.c+COL[dir]]==0&&minn[nod.l+LIN[dir]][nod.c+COL[dir]]>=sor)
                if(!viz[nod.l+LIN[dir]][nod.c+COL[dir]]){
                    q.push(Node(nod.l+LIN[dir],nod.c+COL[dir]));
                    viz[nod.l+LIN[dir]][nod.c+COL[dir]]=true;
                }
        q.pop();
    }
    return false;
}
void bsearch(){
    int p=1<<20;
    int pos=0,r=-1;
    while(p){
        for(int i=1;i<=n;i++)
            memset(viz[i],0,sizeof(viz[i]));
        sor=pos+p;
        if(ok(st)){
            pos+=p;
            r=pos;
        }
        p/=2;
    }
    if(r==-1){
        sor=0;
        if(ok(st))
            printf("0");
        else
            printf("-1");
    }
    else
        printf("%d",r);
}
char s[N+1];
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");
        gets(s);
        for(int j=1;j<=m;j++){
            char c=s[j-1];
            if(c=='*')
                a[i][j]=1;
            else if(c=='D')
                dragons[++d]=Node(i,j);
            else if(c=='I')
                st=Node(i,j);
            else if(c=='O')
                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;
    bfs();
    bsearch();
    return 0;
}