• aoj0121


    一、题意:类似于华容道,输入是8个数字,输入虽然是一行,但实际是以两行的方式操作的。0表示空位,别的相邻数字可移动到该位置上。求最少移动步骤得到指定的状态。

    二、思路:这题可以用BFS来解决。因为在每一步可以产生两个状态,类似于走迷宫里的移动,不同的是这里的坐标变化是一维的:+1,-1,+4,-4。这里需要注意一点是坐标3不能+1,坐标4不能-1,因为这里是排两行的,所以这个小细节很关键。每个状态可以用字符串和0的坐标0来存储(map),并且可以用改字符串对应的整数来标记该状态是否出现过已达到剪枝的效果。这里用到了几个小技巧:1、int类型和string类型的相互转换  2、map的使用。用map来记录到各个状态的步数。如果用数组来存,会MLE。 3.打表。这个很关键,因为逆向思维来说,初始状态都是“01234567”,所以打表后后面直接查表,效率会高很多,不然会TLE。 4.pair函数的使用。用一个pair类型的队列来记录每一个状态以及这个状态下0的位置。 5.在做坐标交换时,我自定义了一个Change函数,也可以用系统自带的swap函数,更简洁。

    三、代码:

    #include"iostream"
    #include"stdio.h"
    #include"queue"
    #include"string.h"
    #include"map"
    #include"sstream"
    #include"stdlib.h"
    using namespace std;
    
    typedef pair<string,int> P;
    
    int inputSample[10];
    string inputString;
    map<string,int>state;
    
    string Int2String(int &a)
    {
        ostringstream oss;
        oss<<a;
        return oss.str();
    }
    
    bool Judge(int x)
    {
        if(x>=0&&x<8) return true;
        return false;
    }
    
    string Change(int a,int b,string str)
    {
        char tmp=str[a];
        str[a]=str[b];
        str[b]=tmp;
    
        return str;
    }
    
    int Bfs()
    {
        queue<P> que;
    
        que.push(P("01234567",0));
        while(que.size())
        {
            P p=que.front();que.pop();
    
            int dir[4]={1,-1,4,-4};
    
            for(int i=0;i<4;i++)
            {
                if(p.second==3&&dir[i]==1) continue;
                if(p.second==4&&dir[i]==-1) continue;
                int nx=p.second+dir[i];
                if(Judge(nx))
                {
                    string str=Change(p.second,nx,p.first);
                    if(state.find(str)==state.end())
                    {
                        state[str]=state[p.first]+1;
                        que.push(P(str,nx));
                    }
                }
            }
        }
        return -1;
    }
    
    int main()
    {
       // freopen("in.txt","r",stdin);
       // freopen("out.txt","w",stdout);
        state["01234567"]=0;
        Bfs();
        while(scanf("%d",&inputSample[0])==1)
        {
            for(int i=1;i<8;i++)
                cin>>inputSample[i];
            inputString="";
    
            for(int i=0;i<8;i++)
            {
                inputString+=Int2String(inputSample[i]);
            }
    
            cout<<state[inputString]<<endl;
        }
        return 0;
    }
    

      

      

  • 相关阅读:
    VMware三个版本workstation、server、esxi的区别
    vmwarevsphere与vmwareworkstation的区别
    PubMed、MEDLINE和PMC
    1000个并发线程,10台机器,每台机器4核,设计线程池大小(转)
    Internet与Intranet
    VMware安装操作系统鼠标失灵
    超详细SQL SERVER 2016跨网段和局域网发布订阅配置图解和常见问题
    一篇理解什么是CanSet, CanAddr?
    collection v1.3.1升级全记录
    我写的诗
  • 原文地址:https://www.cnblogs.com/acm-jing/p/9590019.html
Copyright © 2020-2023  润新知