• 《算法竞赛进阶指南》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;
        }
    }
  • 相关阅读:
    分布式缓存技术redis学习系列(一)——redis简介以及linux上的安装
    redis整合spring(redisTemplate工具类)
    架构之路之spring+redis的集成
    java之redis篇(spring-data-redis整合)
    Redis 安装
    java对redis的基本操作
    mybatis 详解(九)------ 一级缓存、二级缓存
    mybatis 详解(八)------ 懒加载
    mybatis 详解(七)------一对一、一对多、多对多
    mybatis 详解(六)------通过mapper接口加载映射文件
  • 原文地址:https://www.cnblogs.com/randy-lo/p/13167693.html
Copyright © 2020-2023  润新知