蓝桥杯 九宫重排

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xcd1997/article/details/79672134
问题描述
  如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。

  我们把第一个图的局面记为:12345678.
  把第二个图的局面记为:123.46758
  显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
  本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
输入格式
  输入第一行包含九宫的初态,第二行包含九宫的终态。
输出格式
  输出最少的步数,如果不存在方案,则输出-1。
样例输入
12345678.
123.46758
样例输出
3
样例输入
13524678.
46758123.
样例输出
22

 这道题刚看题我们首先想到广搜,从一个状态搜到另一个状态,方向上下左右,判断特殊情况不能走,停止状态是所有情况搜完,但是只由开始状态搜到结束状态只能过60分,时间超限,所以双向搜索,开始状态结束状态一起搜,搜到都能到达的状态结束。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<iostream>
#include<string>
#include<queue>
#define MOD 1000000007
using namespace std;
int fx[4]={-1,1,-3,3};
struct tx
{
    int x,bs;
    string tu;
};
map<string,int>bj;///存开始状态搜到的图和到达此状态所需要的步数
map<string,int>bt;///存结束状态搜到的图和到达此状态所需要的步数
queue<tx>q;///开始状态
queue<tx>p;///结束状态
int dfs(string a,int wz,string enl,int x1)
{

    tx be,en,be1,en1;
    be.bs=0;
    be.x=wz;
    be.tu=a;
    q.push(be);///开始状态入队
    bj[be.tu]=1;
    be1.bs=0;
    be1.tu=enl;
    be1.x=x1;
    p.push(be1);///结束状态入队
    bt[be1.tu]=1;
    while(!q.empty()){///判断是否所有情况搜完
        be1=p.front();
        be=q.front();
        if(be.tu==enl)///判断是否为结束状态
            return be.bs;
        q.pop();
        p.pop();
        for(int i=0;i<4;i++)
        {
            if((be.x%3==0&&i!=0)||(be.x%3==2&&i!=1)||(be.x%3==1)){///判断是否能这样走
                en.bs=be.bs+1;
                if(be.x+fx[i]>=0&&be.x+fx[i]<=8)///判断是否越界
                {
                    en.x=be.x+fx[i];
                    en.tu=be.tu;
                    char st=en.tu[be.x];
                    en.tu[be.x]=en.tu[en.x];
                    en.tu[en.x]=st;
                    if(bt[en.tu]!=0){///判断是否开始状态与结束状态相遇
                       /// printf("%d***%d\n",en.bs,bt[en.tu]);
                        return en.bs+bt[en.tu]-1;
                    }
                    if(bj[en.tu]==0)
                    q.push(en),bj[en.tu]=en.bs+1;
                }
            }
            if((be1.x%3==0&&i!=0)||(be1.x%3==2&&i!=1)||(be1.x%3==1)){
                en1.bs=be1.bs+1;
                if(be1.x+fx[i]>=0&&be1.x+fx[i]<=8)
                {
                    en1.x=be1.x+fx[i];
                    en1.tu=be1.tu;
                    char st=en1.tu[be1.x];
                    en1.tu[be1.x]=en1.tu[en1.x];
                    en1.tu[en1.x]=st;
                    if(bj[en1.tu]!=0){///判断是否开始状态与结束状态相遇
                       /// printf("%d----%d\n",en1.bs,bj[en1.tu]);
                         return en1.bs+bj[en1.tu]-1;///
                    }

                    if(bt[en1.tu]==0){///判断是否走过该状态
                       p.push(en1);
                       bt[en1.tu]=en1.bs+1;
                    }

                }
            }
        }
    }
    return -1;
}
int main()
{
    string a,b;
    int x,x1;
    cin>>a;
    cin>>b;
    for(int i=0;i<a.length();i++)
    {
        if(a[i]=='.')
            x=i;
        if(b[i]=='.')
            x1=i;
    }

    cout<<dfs(a,x,b,x1)<<endl;
    return 0;
}



猜你喜欢

转载自blog.csdn.net/xcd1997/article/details/79672134
今日推荐