zoukankan      html  css  js  c++  java
  • [蓝桥杯2016初赛]卡片换位 BFS

             题目描述

    你玩过华容道的游戏吗?这是个类似的,但更简单的游戏。看下面 3 x 2 的格子
        +---+---+---+
        | A | * | * | 
        +---+---+---+
        | B |   | * |
        +---+---+---+
    在其中放5张牌,其中A代表关羽,B代表张飞,* 代表士兵。还有一个格子是空着的。
    你可以把一张牌移动到相邻的空格中去(对角不算相邻)。
    游戏的目标是:关羽和张飞交换位置,其它的牌随便在哪里都可以。

    输入

    输入存在多组测试数据,对于每组测试数据:
    输入两行6个字符表示当前的局面

    输出

    对于每组测试数据输出一个整数表示答案

    样例输入 Copy

    * A
    **B
    A B
    ***

    样例输出 Copy

    17
    12

    题解:

    1、因为棋盘只有两行,可以把他处理成一行处理(BFS的时候方便标记这个棋盘状态),注意隔离边界(用#将第一行和第二行隔离)

    2、用set集合记录走过的每一个状态,标记走过的棋盘状态

    3、从空格位置开始搜索,目标状态是棋盘中A、B位置互换

    #include<iostream>
    #include<queue>
    #include<algorithm>
    #include<set>
    using namespace std;
    int dir[4]={-1,1,4,-4};//左右下上
    struct node
    {
        int x;
        string s;//保存不同的图,同时用set去标记
        int cnt;
    }A,B,K;
    void bfs()
    {
        queue<node>p;
        p.push(K);
        set<string>se;
        se.insert(K.s);
        while(!p.empty())
        {
            node now=p.front();
            p.pop();   
            for(int i=0;i<4;i++)
            {
                string ss=now.s;
                int tx=now.x+dir[i];
                if((tx>=0&&tx<3)||(tx>3&&tx<7))
                {
                    char h=ss[now.x];
                    ss[now.x]=ss[tx];
                    ss[tx]=h;
                    node temp;
                    temp.x=tx;
                    temp.s=ss;
                    temp.cnt=now.cnt+1;
                    if(ss[B.x]=='A'&&ss[A.x]=='B')
                    {
                        cout<<temp.cnt<<endl;
                        //cout<<temp.s<<endl;
                        return ;
                    }
                    if(se.count(ss)==0)//避免往回走,标记棋盘状态
                    {
                        se.insert(ss);
                        p.push(temp);
                    }
                }
            }
        }
    }
    int main()
    {
        string str,s1,s2;
        while(getline(cin,s1))
        {
            getline(cin,s2);
            str=s1+"#"+s2;//把二行的图转化为一行,用#分割第一行和第二行
            for(int i=0;i<7;i++)
            {
                if(str[i]=='A')
                    A.x=i;
                if(str[i]=='B')
                    B.x=i;
                if(str[i]==' ')
                    K.x=i;
            }
            K.cnt=0;
            K.s=str;
            bfs();
        }
        
        return 0;
    }
  • 相关阅读:
    大数据存储技术_磁盘与阵列技术
    OpenMP Programming
    大数据存储技术_背景
    群ping
    Markdown使用说明
    随笔记录--清楚sqlserver r2 的连接记录
    ORACLE备份保留策略CONFIGURE RETENTION POLICY
    ORA-00257:archiver error.Connect internal only, until freed
    expdp数据泵导出日志信息不全的问题
    处理程序“ExtensionlessUrlHandler-Integrated-4.0”在其模块列表中有一个错误模块“ManagedPipelineHandler”
  • 原文地址:https://www.cnblogs.com/-citywall123/p/12313014.html
Copyright © 2011-2022 走看看