《算法竞赛进阶指南》0x25广度优先搜索 POJ3322 Bloxorz I

题目链接:http://poj.org/problem?id=3322

这题并不难,理解了状态空间的纬度就很容易实现,其中状态是坐标、躺着的起始位置,躺着的形式。

搜索题目比较考验写代码的能力。

代码:

#include<iostream>
#include<cstdio>
#include<queue>
#include<string.h>
using namespace std;
#define maxn 510
char s[maxn][maxn];
int n,m;
bool vis[maxn][maxn][3];
struct node{
    int x,y,lie,step;
};
node st,ed;
int dx[]={0,0,-1,1},dy[]={-1,1,0,0};
//下一跳状态 
int next_x[3][4]={{0,0,-2,1},{0,0,-1,1},{0,0,-1,2}};
int next_y[3][4]={{-2,1,0,0},{-1,2,0,0},{-1,1,0,0}};
int next_lie[3][4]={{1,1,2,2},{0,0,1,1},{2,2,0,0}}; 
int validation(int x,int y){
    return x>=1 && x<=n && y>=1 && y<=m;
}
bool valid(node &a){
    if(!validation(a.x,a.y))return false;
    if(s[a.x][a.y]=='#')return false;
    if(a.lie==0 && s[a.x][a.y]!='.')return false;
    if(a.lie==1 && (!validation(a.x,a.y+1) || s[a.x][a.y+1]=='#'))return false;
    if(a.lie==2 && (!validation(a.x+1,a.y) || s[a.x+1][a.y]=='#'))return false;
    return true;
}
int bfs(){
    queue<node> q;
    vis[st.x][st.y][st.lie]=1;
    q.push(st);
    while(!q.empty()){
        node cur=q.front();
        q.pop();
        if(cur.x==ed.x && cur.y==ed.y && cur.lie==ed.lie){
            return cur.step;
        }
        for(int i=0;i<4;i++){
            node nxt;
            nxt.x=cur.x+next_x[cur.lie][i];
            nxt.y=cur.y+next_y[cur.lie][i];
            nxt.lie=next_lie[cur.lie][i];//注意nxt_lie直接赋值 
            if(!valid(nxt))continue;
            if(vis[nxt.x][nxt.y][nxt.lie])continue;
            vis[nxt.x][nxt.y][nxt.lie]=1;
            nxt.step=cur.step+1;
            q.push(nxt);
        }
    }
    return -1;
}
void pre(){//处理出终点和起点的状态 
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            if(s[i][j]=='O'){
                ed.x=i;
                ed.y=j;
                ed.lie=0;
                s[i][j]='.';
            }
            if(s[i][j]=='X'){
                for(int k=0;k<4;k++){
                    int x=i+dx[k],y=j+dy[k];
                    if(s[x][y]=='X'){
                        st.x=min(i,x),st.y=min(j,y);
                        if(k<2)st.lie=1;
                        else st.lie=2;
                        st.step=0;
                        s[i][j]=s[x][y]='.';
                        break;
                    }
                }
            }
            if(s[i][j]=='X'){
                st.x=i,st.y=j,st.lie=0,st.step=0;
                s[i][j]='.';
            }
        }
}
int main(){
    while(cin>>n>>m && n && m){
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++)scanf("%s",s[i]+1);
        pre();
        int ans=bfs();
        if(ans==-1)cout<<"Impossible"<<endl;
        else cout<<ans<<endl;
    }
}

猜你喜欢

转载自www.cnblogs.com/randy-lo/p/13167693.html