poj 3322 Bloxorz I【广度优先搜索】

来源:互联网 发布:windows xp 键盘鼠标 编辑:程序博客网 时间:2024/05/17 07:33
Bloxorz I
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 5275 Accepted: 1767

Description

Little Tom loves playing games. One day he downloads a little computer game called 'Bloxorz' which makes him excited. It's a game about rolling a box to a specific position on a special plane. Precisely, the plane, which is composed of several unit cells, is a rectangle shaped area. And the box, consisting of two perfectly aligned unit cube, may either lies down and occupies two neighbouring cells or stands up and occupies one single cell. One may move the box by picking one of the four edges of the box on the ground and rolling the box 90 degrees around that edge, which is counted as one move. There are three kinds of cells, rigid cells, easily broken cells and empty cells. A rigid cell can support full weight of the box, so it can be either one of the two cells that the box lies on or the cell that the box fully stands on. A easily broken cells can only support half the weight of the box, so it cannot be the only cell that the box stands on. An empty cell cannot support anything, so there cannot be any part of the box on that cell. The target of the game is to roll the box standing onto the only target cell on the plane with minimum moves.


The box stands on a single cell


The box lies on two neighbouring cells, horizontally


The box lies on two neighbouring cells, vertically

After Little Tom passes several stages of the game, he finds it much harder than he expected. So he turns to your help.

Input

Input contains multiple test cases. Each test case is one single stage of the game. It starts with two integers R and C(3 ≤ R, C ≤ 500) which stands for number of rows and columns of the plane. That follows the plane, which contains R lines and C characters for each line, with 'O' (Oh) for target cell, 'X' for initial position of the box, '.' for a rigid cell, '#' for a empty cell and 'E' for a easily broken cell. A test cases starts with two zeros ends the input.

It guarantees that

  • There's only one 'O' in a plane.
  • There's either one 'X' or neighbouring two 'X's in a plane.
  • The first(and last) row(and column) must be '#'(empty cell).
  • Cells covered by 'O' and 'X' are all rigid cells.

Output

For each test cases output one line with the minimum number of moves or "Impossible" (without quote) when there's no way to achieve the target cell.  

Sample Input

7 7########..X####..##O##....E##....E##.....########0 0

Sample Output

10
题意:有两个单位体积的箱子黏在一起的长方形箱子,在点图上任意滚动(四个方向),求箱子竖直落入目标的
最小步数,其中:
“X”为箱子的初始位置,“O”为目标位置,“#”为障碍物,“E”只能承受一个箱子的重量,“.”可以承受两个箱子
的重量。
分析:虽然这道题不算什么神题但我觉的这是一道很好的搜索题,1,如果不懂脑筋用一般的广搜思维是很难过的
2,这道题很好的体现了搜索中的状态,所谓步不过是从一种状态到另一种状态变化的次数。这是小生对这道题以
及以往广搜的理解,虽然这是些废话(人人都知道)但我觉得对于我这种渣渣在做搜索的过程中对于这句话的理
解与以往越来的不同。
这道题主要的就是标记状态,因为箱子的特殊性(两个单位箱子连在一起),所以状态有很多种,一共有5种,
走的情况有24种,所以这样写起来很麻烦,但是如果我们以一个单位箱子相对与另一个箱子的位置为状态,那么
情况就少了很多,状态有5种,走的情况有5种,如果在精简一下,状态还可以缩成3种,我写的是3中的,状态标
记好了按一般广搜就可以解决了,请君看下代码就明白了。
#include<stdio.h>#include<string.h>#include<algorithm>#include<iostream>#include<queue>using namespace std;const int maxh=500+10;typedef struct Node{    int x,y,z,step;};int dis[maxh][maxh][5],R,C,tx,ty;char map[maxh][maxh];bool ok(int x,int y,int z){    if(x>=1&&x<=R&&y>=1&&y<=C&&map[x][y]!='#'&&!dis[x][y][z])    return true;    return false;}int bfs(int x,int y,int z){    queue<Node>Q;    Node nex1,nex2,fir;    memset(dis,0,sizeof(dis));    dis[x][y][z]=1;    fir.x=x,fir.y=y,fir.z=z,fir.step=0;   // printf(">>>>><%d,%d,%d>\n",fir.x,fir.y,fir.z);    Q.push(fir);    int h=0;    while(!Q.empty())    {        fir=Q.front();        Q.pop();        if(fir.x==tx&&fir.y==ty&&!fir.z)        return fir.step;        // 0 shu 1 qian 2 hou 3 zuo 4 you        if(fir.z==0)//shu        {            //qian            nex1.x=fir.x-1,nex1.y=fir.y,nex1.z=1;            nex2.x=fir.x-2,nex2.y=fir.y,nex2.z=2;            if(ok(nex1.x,nex1.y,nex1.z)&&ok(nex2.x,nex2.y,nex2.z))            {                nex1.step=fir.step+1;                dis[nex1.x][nex1.y][nex1.z]=1;                dis[nex2.x][nex2.y][nex2.z]=1;                Q.push(nex1);            }            //hou            nex1.x=fir.x+1,nex1.y=fir.y,nex1.z=2;            nex2.x=fir.x+2,nex2.y=fir.y,nex2.z=1;            if(ok(nex1.x,nex1.y,nex1.z)&&ok(nex2.x,nex2.y,nex2.z))            {                nex2.step=fir.step+1;                dis[nex1.x][nex1.y][nex1.z]=1;                dis[nex2.x][nex2.y][nex2.z]=1;                Q.push(nex2);            }            //zuo            nex1.x=fir.x,nex1.y=fir.y-1,nex1.z=3;            nex2.x=fir.x,nex2.y=fir.y-2,nex2.z=4;            if(ok(nex1.x,nex1.y,nex1.z)&&ok(nex2.x,nex2.y,nex2.z))            {                nex1.step=fir.step+1;                dis[nex1.x][nex1.y][nex1.z]=1;                dis[nex2.x][nex2.y][nex2.z]=1;                Q.push(nex1);            }            //you            nex1.x=fir.x,nex1.y=fir.y+1,nex1.z=4;            nex2.x=fir.x,nex2.y=fir.y+2,nex2.z=3;            if(ok(nex1.x,nex1.y,nex1.z)&&ok(nex2.x,nex2.y,nex2.z))            {                nex2.step=fir.step+1;                dis[nex1.x][nex1.y][nex1.z]=1;                dis[nex2.x][nex2.y][nex2.z]=1;                Q.push(nex2);            }        }        if(fir.z==1)//qian        {            //qian            nex1.x=fir.x-2,nex1.y=fir.y,nex1.z=0;            if(ok(nex1.x,nex1.y,nex1.z)&&map[nex1.x][nex1.y]=='.')            {                nex1.step=fir.step+1;                dis[nex1.x][nex1.y][nex1.z]=1;                Q.push(nex1);            }            //hou            nex1.x=fir.x+1,nex1.y=fir.y,nex1.z=0;            if(ok(nex1.x,nex1.y,nex1.z)&&map[nex1.x][nex1.y]=='.')            {                nex1.step=fir.step+1;                dis[nex1.x][nex1.y][nex1.z]=1;                Q.push(nex1);            }            //zuo            nex1.x=fir.x,nex1.y=fir.y-1,nex1.z=1;            nex2.x=fir.x-1,nex2.y=fir.y-1,nex2.z=2;            if(ok(nex1.x,nex1.y,nex1.z)&&ok(nex2.x,nex2.y,nex2.z))            {                nex1.step=fir.step+1;                dis[nex1.x][nex1.y][nex1.z]=1;                dis[nex2.x][nex2.y][nex2.z]=1;                Q.push(nex1);            }            //you            nex1.x=fir.x,nex1.y=fir.y+1,nex1.z=1;            nex2.x=fir.x-1,nex2.y=fir.y+1,nex2.z=2;            if(ok(nex1.x,nex1.y,nex1.z)&&ok(nex2.x,nex2.y,nex2.z))            {                nex1.step=fir.step+1;                dis[nex1.x][nex1.y][nex1.z]=1;                dis[nex2.x][nex2.y][nex2.z]=1;                Q.push(nex1);            }        }        if(fir.z==3)//zuo        {            //qian            nex1.x=fir.x-1,nex1.y=fir.y,nex1.z=3;            nex2.x=fir.x-1,nex2.y=fir.y-1,nex2.z=4;            if(ok(nex1.x,nex1.y,nex1.z)&&ok(nex2.x,nex2.y,nex2.z))            {                dis[nex1.x][nex1.y][nex1.z]=1;                dis[nex2.x][nex2.y][nex2.z]=1;                nex1.step=fir.step+1;                Q.push(nex1);            }            //hou            nex1.x=fir.x+1,nex1.y=fir.y,nex1.z=3;            nex2.x=fir.x+1,nex2.y=fir.y-1,nex2.z=4;            if(ok(nex1.x,nex1.y,nex1.z)&&ok(nex2.x,nex2.y,nex2.z))            {                dis[nex1.x][nex1.y][nex1.z]=1;                dis[nex2.x][nex2.y][nex2.z]=1;                nex1.step=fir.step+1;                Q.push(nex1);            }            //zuo            nex1.x=fir.x,nex1.y=fir.y-2,nex1.z=0;            if(ok(nex1.x,nex1.y,nex1.z)&&map[nex1.x][nex1.y]=='.')            {                   dis[nex1.x][nex1.y][nex1.z]=1;                nex1.step=fir.step+1;                Q.push(nex1);            }            //you            nex1.x=fir.x,nex1.y=fir.y+1,nex1.z=0;            if(ok(nex1.x,nex1.y,nex1.z)&&map[nex1.x][nex1.y]=='.')            {                   dis[nex1.x][nex1.y][nex1.z]=1;                nex1.step=fir.step+1;                Q.push(nex1);            }        }    }    return -1;}int main(){    int time,h,s[2][2];    while(~scanf("%d%d",&R,&C)&&(R+C))    {        for(int i=1;i<=R;i++)        scanf("%s",map[i]+1);        h=0;        for(int i=1;i<=R;i++)        for(int j=1;j<=C;j++)        {            if(map[i][j]=='X')            {                   map[i][j]='.';                s[h][0]=i;                s[h][1]=j;                h++;            }            if(map[i][j]=='O')            {                map[i][j]='.';                tx=i;                ty=j;            }        }          if(h==1)        {               time=bfs(s[0][0],s[0][1],0);        }        else        {               if(s[0][0]==s[1][0])            {                time=bfs(s[1][0],s[1][1],3);            }            else            {                time=bfs(s[1][0],s[1][1],1);            }        }        if(time==-1)        {            printf("Impossible\n");        }        else        {            printf("%d\n",time);        }    }    return 0;}
0 0
原创粉丝点击