【loj-1055-Going Together-三个棋子推箱子走到目的地--讲预判的bfs】

light oj 1055-Going Together

题目大致意思:

  简单的三个棋子,每次可以下达一个命令,robots全部按照指令进行前进;若下一步不为空地则停留在原地。
  特殊考虑:
     1.例如ABC.....,(或者AB#...C——C需要再次向左移动,AB则不能再次移动)A已经在边界上;这时命令三个棋子全部向左前进,AB就挤到了一块去——然后依次撤回到上一步初始的now状态,至少跑两次循环!
                 2.或者,ABC每次移动单个棋子时,先首先预判  移动的地方是否有空闲位置!注意ABC连在一块就当不存在处理,因为ABC在一块向左向右都OK可以动!

 特别注意:

  A single command will be activated for the three robots simultaneously.(因为理解错了题意,当成三个旗子可以随意朝向而不是统一朝向!看我下一篇博客,泪~~)
 
/*
//下面 极大值测试
9
AB....C..
.........
.........
.........
.........
.........
.........
.........
X..X..X..

*/

#include<stdio.h>
#include<math.h>
#include<iostream>
#include<string.h>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
#define N 10
#define inf 0x3f3f3f3f
char mp[N][N];
int n;
struct node{
    int x,y;
};
struct group{//一个局面三个点的位置,位置之间等价
    node p[3];//0,1,2三位有效存储
    int step;
}st;
int dir[4][2]={{1,0},{0,1},{0,-1},{-1,0} };
bool vis[N][N][N][N][N][N];//标记数组,模拟每一组棋子组合成的局面
bool judge_end(group x){  //判断当前局面是否达到结束要求
    int num=0;
    for(int i=0;i<3;i++){
            if(mp[x.p[i].x][x.p[i].y]=='X')
                num++;
    }
    if(num==3)return true;
    return false;
}
bool judge_node(node a){
    if(a.x>=0&&a.y>=0&&a.x<n&&a.y<n&&mp[a.x][a.y]!='#')
        return true;
    return false;
}
void getvis(group a){//从一个局面获取1个标记即可,剩余5个意义不大(这步在下篇博客上意义较大)
    vis[a.p[0].x][a.p[0].y][a.p[1].x][a.p[1].y][a.p[2].x][a.p[2].y]=true;
   /* vis[a.p[0].x][a.p[0].y][a.p[2].x][a.p[2].y][a.p[1].x][a.p[1].y]=true;
    vis[a.p[1].x][a.p[1].y][a.p[0].x][a.p[0].y][a.p[2].x][a.p[2].y]=true;
    vis[a.p[1].x][a.p[1].y][a.p[2].x][a.p[2].y][a.p[0].x][a.p[0].y]=true;
    vis[a.p[2].x][a.p[2].y][a.p[1].x][a.p[1].y][a.p[0].x][a.p[0].y]=true;
    vis[a.p[2].x][a.p[2].y][a.p[0].x][a.p[0].y][a.p[1].x][a.p[1].y]=true;*/
}
void debug(group a){
    printf("*%dstep* *A*(%d,%d) ",a.step,a.p[0].x,a.p[0].y);
    printf("*B*(%d,%d) ",a.p[1].x,a.p[1].y);
    printf("*C*(%d,%d)\n",a.p[2].x,a.p[2].y);
}
bool cmp(node a,node b){
    return (a.x==b.x)&&(a.y==b.y);
}

int bfs(){
    memset(vis,false,sizeof(vis));
    group now,ne;
    queue<group>Q;
    st.step=0;
    Q.push(st); //标记起点局面
    getvis(st);
    while(Q.size()){
        now=Q.front();
        Q.pop();
        if(judge_end(now))return now.step;

        for(int i=0;i<4;i++){//四种命令的走法
            node p1,p2,p3;
            p1.x=now.p[0].x+dir[i][0];
            p1.y=now.p[0].y+dir[i][1];
            p2.x=now.p[1].x+dir[i][0];
            p2.y=now.p[1].y+dir[i][1];
            p3.x=now.p[2].x+dir[i][0];
            p3.y=now.p[2].y+dir[i][1];
            ne=now;//初始化
            if(judge_node(p1))//p1p2p3表示的下一位置,合法则移动
                ne.p[0]=p1;
            if(judge_node(p2))
                ne.p[1]=p2;
            if(judge_node(p3))
                ne.p[2]=p3;
                //一个格点上只能站一个人,站的人多于一个了,就撤回去
            for(int j=3;j>=0;j--){
                if(cmp(ne.p[0],ne.p[1])||cmp(ne.p[0],ne.p[2]))
                    ne.p[0]=now.p[0];
                if(cmp(ne.p[1],ne.p[0])||cmp(ne.p[1],ne.p[2]))
                    ne.p[1]=now.p[1];
                if(cmp(ne.p[2],ne.p[0])||cmp(ne.p[2],ne.p[1]))
                    ne.p[2]=now.p[2];
            }
            if(vis[ne.p[0].x][ne.p[0].y][ne.p[1].x][ne.p[1].y][ne.p[2].x][ne.p[2].y])
                continue;//已经标记过的
            else
                getvis(ne);
            ne.step=now.step+1;
      //  debug(ne);
            if(judge_end(ne))return ne.step;
            else Q.push(ne);
        }
    }
    return -1;
}
int main()
{
    int T,cas=0;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i=0;i<n;i++)//读图
            scanf("%s",mp[i]);
        int num1=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(mp[i][j]>='A'&&mp[i][j]<='C')
                    st.p[num1].x=i,st.p[num1++].y=j;
            }
        }
        printf("Case %d: ",++cas);
        int ans=bfs();
        if(ans!=-1)
            printf("%d\n",ans);
        else
            printf("trapped\n");
    }

    return 0;
}
View Code

 

posted @ 2018-03-03 16:27  山枫叶纷飞  阅读(187)  评论(0编辑  收藏  举报