• 【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)
    ",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
    ",ans);
            else
                printf("trapped
    ");
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    jq function return value
    danci4
    danci3
    danci2
    项目总结 和语言总结。
    vm 安装 ox 10.13
    ios 异步和多线程
    ios 语法问题 全局变量。
    mvc
    object-c 之autolayout
  • 原文地址:https://www.cnblogs.com/zhazhaacmer/p/8497027.html
Copyright © 2020-2023  润新知