poj 1475 广搜

题意:推箱子    要求在推的次数最少的情况下,人移动次数最少

分析:pu[x1][y1][x2][y2]、mo[x1][y1][x2][y2]记录人在x1,y1 箱子在x2,y2时的最少推动次数和最少人移动次数。

 

 

const int maxn=1000000;
int n,m,pp,p,ans,bestp,bestm;
char c[25][25];
struct node{
    int x1,y1,x2,y2,pus,mov;
    int pre;
    char op;
}nd[maxn];
int mo[20][20][20][20],pu[20][20][20][20];
int tx[]={-1,1,0,0},ty[]={0,0,-1,1};
char dir[]={'n','s','w','e'};
char Dir[]={'N','S','W','E'};
queue<int> q;
stack<int> s;

bool can(int x,int y){
    if(x>=0&&x<n&&y>=0&&y<m)return true;
    return false;
}

void shuchu(int i){
    if(nd[i].pre!=-1){
        shuchu(nd[i].pre);
        cout<<nd[i].op;
    }
}

void solve(){
    while(!q.empty()){
        int v=q.front(); q.pop();
        for(int i=0;i<4;i++){
            int xx1=nd[v].x1+tx[i], yy1=nd[v].y1+ty[i], xx2=nd[v].x2+tx[i],yy2=nd[v].y2+ty[i];
            if(!can(xx1,yy1)||c[xx1][yy1]=='#')continue;
            if(xx1==nd[v].x2&&yy1==nd[v].y2)
                if(!can(xx2,yy2)) continue;

            int flag=0;
            if(s.empty())p=pp++;        //标记p是怎么来的   移动步数大则不入队列
            else {p=s.top();s.pop();flag=1;}
            nd[p].x1=xx1;  nd[p].y1=yy1; nd[p].x2=nd[v].x2; nd[p].y2=nd[v].y2;
            nd[p].pre=v;  nd[p].op=dir[i]; nd[p].mov=nd[v].mov+1; nd[p].pus=nd[v].pus;
            if(xx1==nd[v].x2&&yy1==nd[v].y2){
                nd[p].x2=xx2; nd[p].y2=yy2;
                nd[p].op=Dir[i]; nd[p].pus++;
            }
            if(nd[p].pus<pu[nd[p].x1][nd[p].y1][nd[p].x2][nd[p].y2]||(
               nd[p].pus==pu[nd[p].x1][nd[p].y1][nd[p].x2][nd[p].y2]&&
               nd[p].mov<mo[nd[p].x1][nd[p].y1][nd[p].x2][nd[p].y2])){
                    pu[nd[p].x1][nd[p].y1][nd[p].x2][nd[p].y2]=nd[p].pus;
                    mo[nd[p].x1][nd[p].y1][nd[p].x2][nd[p].y2]=nd[p].mov;
                    if(c[nd[p].x2][nd[p].y2]=='T'){
                        if(bestp>nd[p].pus||(bestp==nd[p].pus&&bestm>nd[p].mov)){
                            bestp=nd[p].pus; bestm=nd[p].mov; ans=p;
                        }
                    }
                    else q.push(p);
               }else{
                    if(flag)s.push(p);
                    else pp--;
               }
        }
    }
}

void read(){
    pp=1; ans=-1; bestp=bestm=999999999;
    while(!q.empty()) q.pop();
    while(!s.empty()) s.pop();
    memset(mo,1,sizeof(mo));
    memset(pu,1,sizeof(pu));
    for(int i=0;i<n;i++){
        cin>>c[i];
        for(int j=0;j<m;j++){
            if(c[i][j]=='S')nd[0].x1=i,nd[0].y1=j;
            else if(c[i][j]=='B')nd[0].x2=i,nd[0].y2=j;
        }
    }
    nd[0].pre=-1; nd[0].pus=nd[0].mov=0;
    q.push(0);
}

int main(){
    int maze=1;
    while(cin>>n>>m){
        if(n==0)break;
        read();
        solve();
        cout<<"Maze #"<<maze++<<endl;
        if(ans==-1) cout<<"Impossible.";
        else shuchu(ans); cout<<endl<<endl;
    }
    return 0;
}

 

 

posted @ 2013-06-20 20:03  心向往之  阅读(143)  评论(0编辑  收藏  举报