zoukankan      html  css  js  c++  java
  • 《算法竞赛进阶指南》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之使用python脚本监控队列长度
    ELK之filebate收集日志传递至Logstash
    [转] SOLID五大设计原则
    [转] 面向对象原则之GOF是招式,九大原则才是精髓
    [转] (CQRS)命令和查询责任分离架构模式(一) 之 什么是CQRS
    [0] 四色原型
    [0] C#软件项目版本号的命名规则及格式介绍
    [0] AssemblyInfo.cs文件介绍
    [0] 服务器 TCP 提供程序无法在 [ 'any' <ipv4> *] 上侦听。TCP 端口已在使用中。
    [0] C#异常种类
  • 原文地址:https://www.cnblogs.com/randy-lo/p/13167693.html
Copyright © 2011-2022 走看看