Bloxorz很有意思的一个游戏(POJ3322)

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

--------------------------------------------------------------------------------------------------------------
游戏很有意思,很智力~有兴趣可以到这个地方去玩玩~
关于这题,没有游戏中那种可以搭桥的情况~也就是说整个maze不会变,那总共就有500*500*5种状态了。
典型的BFS,可以记录其中某个格子的坐标,然后再用一个int变量来记录这个格子和另一个格子的相对位置。
0:上
1:右
2:下
3:左
以上是2个格子没有重叠的情况,假如重叠,那就把状态设为4。
当且仅当格子状态为4,并且位于终点时,才算成功。
4k的代码,写的我手有点麻~
-------------------------------------code----------------------------------------------------------------------
  1. #include<iostream>
  2. #include<queue>
  3. using namespace std;
  4. bool vis[500][500][5];
  5. struct NODE
  6. {
  7.     int i,j,floor,state; 
  8. };
  9. int mv[4][2]={-1,0,0,1,1,0,0,-1},r,c,si[2],sj[2],k;
  10. char maze[501][501];
  11. void init ( )
  12. {
  13.     int i, j;
  14.     k=0;
  15.     memset(vis,0,sizeof(vis));
  16.     for ( i=0 ; i<r ; i++ )
  17.     {
  18.         scanf("%s",maze[i]);
  19.         for ( j=0 ; j<c ; j++ )
  20.             if ( maze[i][j]=='X' )
  21.                 si[k]=i,sj[k++]=j;
  22.     }
  23. }
  24. // 返回两个点的相对位置的状态
  25. int mark ( int p1, int q1 , int p2 , int q2 )
  26. {
  27.     if ( p2-p1==-1 && q2-q1==0 )
  28.         return 0;
  29.     if ( p2-p1==0 && q2-q1==1 )
  30.         return 1;
  31.     if ( p2-p1==1 && q2-q1==0 )
  32.         return 2;
  33.     if ( p2-p1==0 && q2-q1==-1 )
  34.         return 3;
  35. }
  36. void bfs ( )
  37. {
  38.     NODE temp,head;
  39.     queue<NODE> que;
  40.     int i,tm1,tn1,tm2,tn2;
  41.     if ( k==1 )
  42.     {
  43.         head.i=si[0],head.j=sj[0];
  44.         head.floor=0;
  45.         head.state=4;
  46.         que.push(head);
  47.         vis[head.i][head.j][4]=vis[head.i][head.j][5]=true;
  48.     }
  49.     else
  50.     {
  51.         head.i=si[0],head.j=sj[0];
  52.         head.floor=0;
  53.         head.state=mark(si[0],sj[0],si[1],sj[1]);
  54.         que.push(head);
  55.         vis[si[0]][sj[0]][mark(si[0],sj[0],si[1],sj[1])]=vis[si[1]][sj[1]][mark(si[1],sj[1],si[0],sj[0])]=true;
  56.     }
  57.     while ( !que.empty() )
  58.     {
  59.         head=que.front();
  60. //      cout<<"*******************************"<<endl;
  61.         //if ( head.state>3 )
  62.         //  cout<<head.i<<" "<<head.j<<" "<<head.floor<<" out"<<endl;
  63.         //else
  64.         //  cout<<head.i<<" "<<head.j<<" "<<head.i+mv[head.state][0]<<" "<<head.j+mv[head.state][1]<<" "<<head.floor<<" out"<<endl;
  65.         que.pop() ;
  66. // 先考虑2个格子重叠的状态
  67.         if ( head.state>3 )
  68.             for ( i=0 ; i<4 ; i++ )
  69.             {
  70.                 tm1=head.i+mv[i][0],tn1=head.j+mv[i][1];
  71.                 tm2=tm1+mv[i][0],tn2=tn1+mv[i][1];
  72.                 if ( tm2>=0 && tm2<r && tn2>=0 && tn2<c && maze[tm1][tn1]!='#' && maze[tm2][tn2]!='#' 
  73.                     && !vis[tm1][tn1][mark(tm1,tn1,tm2,tn2)] && !vis[tm2][tn2][mark(tm2,tn2,tm1,tn1)] )
  74.                 {
  75.                     vis[tm1][tn1][mark(tm1,tn1,tm2,tn2)]=vis[tm2][tn2][mark(tm2,tn2,tm1,tn1)]=true;
  76.                     temp.i=tm1,temp.j=tn1,temp.floor=head.floor+1,temp.state=mark(tm1,tn1,tm2,tn2);
  77.                     que.push(temp);
  78.                     //if ( temp.state>3 )
  79.                     //  cout<<temp.i<<" "<<temp.j<<" "<<temp.floor<<" in"<<endl;
  80.                     //else
  81.                     //  cout<<temp.i<<" "<<temp.j<<" "<<temp.i+mv[temp.state][0]<<" "<<temp.j+mv[temp.state][1]<<" "<<temp.floor<<" in"<<endl;
  82.                 }
  83.             }
  84.         else
  85.         {
  86.             for ( i=0 ; i<4 ; i++ )
  87.             {
  88.                 if ( i==head.state || i==(head.state+2)%4 )
  89.                     continue;
  90.                 tm1=head.i+mv[i][0],tn1=head.j+mv[i][1];
  91.                 tm2=tm1+mv[head.state][0],tn2=tn1+mv[head.state][1];
  92.                 if ( tm1>=0 && tm1<r && tn1>=0 && tn1<c  && tm2>=0 && tm2<r && tn2>=0 && tn2<c && maze[tm1][tn1]!='#' && maze[tm2][tn2]!='#' 
  93.                     && !vis[tm1][tn1][head.state] && !vis[tm2][tn2][(head.state+2)%4] )
  94.                 {
  95.                     vis[tm1][tn1][head.state]=vis[tm2][tn2][(head.state+2)%4]=true;
  96.                     temp.i=tm1,temp.j=tn1,temp.floor=head.floor+1,temp.state=head.state;
  97.                     que.push(temp);
  98.                     //if ( temp.state>3 )
  99.                     //  cout<<temp.i<<" "<<temp.j<<" "<<temp.floor<<" in"<<endl;
  100.                     //else
  101.                     //  cout<<temp.i<<" "<<temp.j<<" "<<temp.i+mv[temp.state][0]<<" "<<temp.j+mv[temp.state][1]<<" "<<temp.floor<<" in"<<endl;
  102.                 }
  103.             }
  104.             tm1=head.i+mv[(head.state+2)%4][0],tn1=head.j+mv[(head.state+2)%4][1];
  105.             if ( tm1>=0 && tm1<r && tn1>=0 && tn1<c && maze[tm1][tn1]!='#' && maze[tm1][tn1]!='E' 
  106.                 && !vis[tm1][tn1][4] )
  107.             {
  108.                 if (maze[tm1][tn1]=='O')
  109.                 {
  110.                     printf("%d/n",head.floor+1);
  111.                     return ;
  112.                 }
  113.                 vis[tm1][tn1][4]=true;
  114.                 temp.i=tm1,temp.j=tn1,temp.floor=head.floor+1,temp.state=4;
  115.                 que.push(temp);
  116.                 //if ( temp.state>3 )
  117.                 //      cout<<temp.i<<" "<<temp.j<<" "<<temp.floor<<" in"<<endl;
  118.                 //  else
  119.                 //      cout<<temp.i<<" "<<temp.j<<" "<<temp.i+mv[temp.state][0]<<" "<<temp.j+mv[temp.state][1]<<" "<<temp.floor<<" in"<<endl;
  120.             }
  121.             tm1+=3*mv[head.state][0],tn1+=3*mv[head.state][1];
  122.             if ( tm1>=0 && tm1<r && tn1>=0 && tn1<c && maze[tm1][tn1]!='#' && maze[tm1][tn1]!='E' 
  123.                 && !vis[tm1][tn1][4] )
  124.             {
  125.                 if ( maze[tm1][tn1]=='O' )
  126.                 {
  127.                     printf("%d/n",head.floor+1);
  128.                     return ;
  129.                 }
  130.                 vis[tm1][tn1][4]=true;
  131.                 temp.i=tm1,temp.j=tn1,temp.floor=head.floor+1,temp.state=4;
  132.                 que.push(temp);
  133.                 /*if ( temp.state>3 )
  134.                         cout<<temp.i<<" "<<temp.j<<" "<<temp.floor<<" in"<<endl;
  135.                     else
  136.                         cout<<temp.i<<" "<<temp.j<<" "<<temp.i+mv[temp.state][0]<<" "<<temp.j+mv[temp.state][1]<<" "<<temp.floor<<" in"<<endl;*/
  137.             }
  138.         }
  139.     }
  140.     printf("Impossible/n");
  141. }
  142. int main ( )
  143. {
  144.     //freopen("ans.txt","w",stdout);
  145.     while ( scanf("%d%d",&r,&c) && r && c )
  146.     {
  147.         init();
  148.         bfs();
  149.     }
  150. }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值