版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xcd1997/article/details/79672134
问题描述
如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。
我们把第一个图的局面记为:12345678.
把第二个图的局面记为:123.46758
显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
我们把第一个图的局面记为:12345678.
把第二个图的局面记为:123.46758
显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
输入格式
输入第一行包含九宫的初态,第二行包含九宫的终态。
输出格式
输出最少的步数,如果不存在方案,则输出-1。
样例输入
12345678.
123.46758
123.46758
样例输出
3
样例输入
13524678.
46758123.
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;
}