对不同的状态搜索

poj 3322 Bloxorz I


题意:
  给你一个箱子和箱子开始时摆放的方式,通过滚动箱子将其摆放到目标位置,其中有三种地板状态(坚硬的,易碎的,空的)分别能承受不同的箱子重量,求出最少滚动的次数。
分析:
  用三维数组标记走过的状态,每次只需记录一个格子的情况。
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<vector>
#include<stack>
#include<cstdlib>

//#define LL __int64
#define LL long long
#define pi acos(-1.0)
#define PB push_back()
#define MP make_pair()
#define BG begin()
#define ED end()
#define clr(a,b)  memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define Mod  1e9+7
using namespace std;
const int maxn=505;
char A[maxn][maxn];
int vis[maxn][maxn][3];
int n,m;

struct node
{
    int x,y,w;
    int step;
};

bool judge(int x,int y)
{
     return x>=0&&x<n&&y>=0&&y<m;
}

bool judge1(int x,int y,int w)
{
    if(judge(x,y)&&A[x][y]!='#'){
        if(w==0)
            return  A[x][y]!='E';
        else if(w==1)
            return  judge(x,y+1)&&A[x][y+1]!='#';
        else if(w==2)
            return   judge(x+1,y)&&A[x+1][y]!='#';
    }
    else
        return 0;
}

int dir[4][2]={0,-1,1,0,0,1,-1,0};

int slove(int sx,int sy,int sw)
{
    queue<node> Q;
    node st,ed;
    int dx,dy,dw,ds;
    st.x=sx;
    st.y=sy;
    st.w=sw;
    st.step=0;
    Q.push(st);
    vis[sx][sy][sw]=1;
    while(!Q.empty())
     {
         st=Q.front();
         Q.pop();
         if(A[st.x][st.y]=='O'&&st.w==0){
            return st.step;
         }
         for(int i=0;i<4;i++){
             dx=st.x+dir[i][0];
             dy=st.y+dir[i][1];
             ds=st.step+1;
            if(st.w==0)
            {
                if(i==0){
                     dy--;
                     dw=1;
                }
                else if(i==1){
                    dw=2;
                }
                else if(i==2){
                    dw=1;
                }
                else if(i==3){
                     dx--;
                     dw=2;
                }
            }
            else if(st.w==1)
            {
                if(i==0){
                      dw=0;
                }
                else if(i==1){
                    dw=1;
                }
                else if(i==2){
                     dy++;
                     dw=0;
                }
                else if(i==3){
                      dw=1;
                }
            }
            else if(st.w==2)
            {
                if(i==0){
                      dw=2;
                }
                else if(i==1){
                    dx++;
                    dw=0;
                }
                else if(i==2){
                      dw=2;
                }
                else if(i==3){
                      dw=0;
                }
            }
            if(judge1(dx,dy,dw)&&!vis[dx][dy][dw])
            {
                vis[dx][dy][dw]=1;
                ed.x=dx;
                ed.y=dy;
                ed.w=dw;
                ed.step=ds;
                Q.push(ed);
            }
         }
     }
     return 0;

}
int main()
{
     #ifndef ONLINE_JUDGE
      freopen("in.cpp","r",stdin);
     #endif // ONLINE_JUDGE
      while(~scanf("%d%d",&n,&m))
      {
          if(n==0&&m==0)  break;
          bool flag=0;
          int sx,sy,sw;
          clr(vis,0);
          for(int i=0;i<n;i++){
             scanf("%s",A[i]);
            for(int j=0;j<m;j++){
                  if(A[i][j]=='X'){
                      if(!flag)
                      {
                          flag=1;
                          sx=i;
                          sy=j;
                          sw=0;
                      }
                      else{
                         if(judge(i-1,j)&&A[i-1][j]=='X')
                             sw=2;
                         else if(judge(i,j-1)&&A[i][j-1]=='X')
                             sw=1;
                         }
                      }
                  }
            }
          int cnt=slove(sx,sy,sw);
          if(cnt)
            printf("%d\n",cnt);
          else
            puts("Impossible");

      }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值