POJ

来源:互联网 发布:淘宝无线端链接 编辑:程序博客网 时间:2024/06/05 12:49

Bloxorz I

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




解题报告:简单的BFS,与以往不同的是,这次不是一个一个格子的走,是一个或两个,只是代码写起来比较麻烦,其他都一样。vis数组采用vis[505][505][5],第三维的5代表5种状态,0代表在该格子是竖直向上,1代表向左横着,2代表向上竖着,3代表向右横着,4代表向下竖着。可以优化成3种状态,但是5种容易写代码。详见代码。

另外用cin会超时!!!!!!!!!


#include <iostream>#include <stdio.h>#include <stdlib.h>#include <vector>#include <map>#include <string.h>#include <algorithm>#include <queue>using namespace std;int N,M;char maze[505][505];bool vis[505][505][5];struct point{    int x1,y1;//两个点,x1,y1永远在x2,y2前    int x2,y2;    int t;    point(int a=0,int b=0,int c=0,int d=0,int f=0){        x1=a;        y1=b;        x2=c;        y2=d;        t=f;    }};//检查该状态是否可以去到bool check(point tp){        //如果是竖直向上    if(tp.x1==tp.x2&&tp.y1==tp.y2){        //判断是否是#或E        if(maze[tp.x1][tp.y1]=='#'||maze[tp.x1][tp.y1]=='E')            return false;    }    else{        if(maze[tp.x1][tp.y1]=='#'||maze[tp.x2][tp.y2]=='#')            return false;    }    //看该状态是否来过    if(tp.x2==tp.x1&&tp.y1==tp.y2){        if(vis[tp.x1][tp.y1][0])            return false;    }    else{        if(tp.x2-tp.x1!=0){            if(vis[tp.x1][tp.y1][4]||vis[tp.x2][tp.y2][2])                return false;        }        else{            if(vis[tp.x1][tp.y1][3]||vis[tp.x2][tp.y2][1])                return false;        }    }    return true;}int bfs(point start){    queue<point> que;    que.push(start);    //标记初始状态    if(start.x2==start.x1&&start.y1==start.y2)        vis[start.x1][start.y1][0]=1;    else{        if(start.x2-start.x1!=0){            vis[start.x1][start.y1][4]=1;            vis[start.x2][start.y2][2]=1;        }        else{            vis[start.x1][start.y1][3]=1;            vis[start.x2][start.y2][1]=1;        }    }    while(!que.empty()){        point tp=que.front();        que.pop();        //保证x1,y1比x2y2小        if(tp.x2<tp.x1){            swap(tp.x1,tp.x2);            swap(tp.y1,tp.y2);        }        if(tp.y2<tp.y1){            swap(tp.x1,tp.x2);            swap(tp.y1,tp.y2);        }        //如果到了终点        if(tp.x1==tp.x2&&tp.y1==tp.y2){            if(maze[tp.x1][tp.y1]=='O')                return tp.t;        }        //如果是竖直向上,可以向四个方向倒下        if(tp.x1==tp.x2&&tp.y1==tp.y2){                        point temp=tp;            temp.x1++;            temp.x2+=2;            temp.t++;            if(check(temp)){                que.push(temp);                vis[temp.x1][temp.y1][4]=1;                vis[temp.x2][temp.y2][2]=1;            }            temp=tp;            temp.x1-=2;            temp.x2--;            temp.t++;            if(check(temp)){                que.push(temp);                vis[temp.x1][temp.y1][4]=1;                vis[temp.x2][temp.y2][2]=1;            }            temp=tp;            temp.y1++;            temp.y2+=2;            temp.t++;            if(check(temp)){                que.push(temp);                vis[temp.x1][temp.y1][3]=1;                vis[temp.x2][temp.y2][1]=1;            }            temp=tp;            temp.y1-=2;            temp.y2--;            temp.t++;            if(check(temp)){                que.push(temp);                vis[temp.x1][temp.y1][3]=1;                vis[temp.x2][temp.y2][1]=1;            }        }        else{            //如果是竖着放,可以向前向后变成直立,或者向左向右滚            if(tp.x2-tp.x1!=0){                point temp=tp;                temp.x1--;                temp.x2=temp.x1;                temp.t++;                if(check(temp)){                    que.push(temp);                    vis[temp.x1][temp.y1][0]=1;                }                temp=tp;                temp.x2++;                temp.x1=temp.x2;                temp.t++;                if(check(temp)){                    que.push(temp);                    vis[temp.x1][temp.y1][0]=1;                }                temp=tp;                temp.y1--;                temp.y2--;                temp.t++;                if(check(temp)){                    que.push(temp);                    vis[temp.x1][temp.y1][4]=1;                    vis[temp.x2][temp.y2][2]=1;                }                temp=tp;                temp.y1++;                temp.y2++;                temp.t++;                if(check(temp)){                    que.push(temp);                    vis[temp.x1][temp.y1][4]=1;                    vis[temp.x2][temp.y2][2]=1;                }            }            else{                //如果是横着放,可以向左向右变成直立,或者向前向后滚                point temp=tp;                temp.y1--;                temp.y2=temp.y1;                temp.t++;                if(check(temp)){                    que.push(temp);                    vis[temp.x1][temp.y1][0]=1;                }                temp=tp;                temp.y2++;                temp.y1=temp.y2;                temp.t++;                if(check(temp)){                    que.push(temp);                    vis[temp.x1][temp.y1][0]=1;                }                temp=tp;                temp.x1--;                temp.x2--;                temp.t++;                if(check(temp)){                    que.push(temp);                    vis[temp.x1][temp.y1][3]=1;                    vis[temp.x2][temp.y2][1]=1;                }                temp=tp;                temp.x1++;                temp.x2++;                temp.t++;                if(check(temp)){                    que.push(temp);                    vis[temp.x1][temp.y1][3]=1;                    vis[temp.x2][temp.y2][1]=1;                }            }        }    }    return -1;}int main(){    char str[505];    while(scanf("%d%d",&N,&M)&&N&&M){        memset(maze,0,sizeof(maze));        memset(vis,0,sizeof(vis));        for(int i=0;i<=N+1;i++){            maze[i][0]='#';            maze[i][M+1]='#';        }        for(int i=0;i<=M+1;i++){            maze[0][i]='#';            maze[N+1][i]='#';        }        //开始点,要判断是否只有一个点        point temp;        int num=1;        for(int i=1;i<=N;i++){            //要用C的输入,cin会超时            scanf("%s" ,str);            for(int j = 1 ;j <= M ;j ++){                maze[i][j]=str[j-1];                if(maze[i][j]=='X'){                    if(num==1){                        temp.x1=i;                        temp.y1=j;                        num++;                    }                    else{                        temp.x2=i;                        temp.y2=j;                        num++;                    }                    maze[i][j]='.';                }            }        }        //如果只有一个X        if(num==2){            temp.x2=temp.x1;            temp.y2=temp.y1;        }        temp.t=0;        int ans=bfs(temp);        if(ans==-1)            cout<<"Impossible"<<endl;        else            cout<<ans<<endl;            }    return 0;}





原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 在苏宁易购上买东西地址错了怎么办 手机分期付款银行卡丢了怎么办 华硕笔记本鼠标不动了怎么办 韵达快递不派送怎么办 中通快递不派送怎么办 农业银行信用卡密码输错三次怎么办 农业银行卡多次输错密码怎么办 想把店长弄走怎么办 济南银座卡过期了怎么办 银座购物卡丢失后怎么办 银座的卡丢了怎么办 银行卡换了旧卡怎么办 大理市民卡丢了怎么办 市民卡内的钱怎么办 宝付支付乱扣款怎么办 苏宁任性贷逾期怎么办 第二次跟家里开口要钱还网贷怎么办 网贷到家来要钱怎么办 网贷贷不了啦急要钱怎么办 百度推广竞价关键词太长怎么办 药店位置差客流少怎么办 网站上的用词违规怎么办 苹果16g内存不够怎么办 手机16g内存不够怎么办 在私企年纪大了怎么办 谷歌浏览器显示不安全打不开怎么办 4s密码多次错误怎么办 苹果4s手机系统错误怎么办 汽车充电口坏了怎么办 如果手机充不了电怎么办 淘宝买的家电坏了怎么办 衣服皱了没有熨斗怎么办 油烟机油盒坏了怎么办 实体店不给换货怎么办 台式电脑鼠标不动了怎么办 电脑开机一直长鸣报警怎么办 国外电话卡网速太慢怎么办 滴滴提现忘记登录密码怎么办 微信提现支付密码忘记了怎么办 小米手机前置摄像头打不开怎么办 mp4视频屏幕好小怎么办