历届试题 九宫重排 时间限制:1.0s 内存限制:256.0MB 问题描述 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。
我们把第一个图的局面记为:12345678.
把第二个图的局面记为:123.46758
显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。 输入格式 输入第一行包含九宫的初态,第二行包含九宫的终态。 输出格式 输出最少的步数,如果不存在方案,则输出-1。 样例输入 12345678.
123.46758 样例输出 3 样例输入 13524678.
46758123. 样例输出 22
code:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<map>
#define LL long long
using
namespace std;
char s1[
15],s2[
15],maze[
5][
5];
int xx[] = {
1,-
1,
0,
0};
int yy[] = {
0,
0,
1,-
1};
map<LL,
int> mp;
LL s,tot;
struct node{
int x,y,step;
char mi[
3][
3];
}st,ne,tmp;
LL hash(
char dd[
3][
3]){
LL ans =
0;
for(
int i=
0; i<
3; i++)
for(
int j=
0; j<
3; j++)
ans = ans*
10 + dd[i][j] –
‘
0
‘;
return ans;
}
void bfs(
int x,
int y)
{
queue<node> que;
st.x = x,st.y = y;
st.step =
0;
for(
int i=
0; i<
3; i++)
for(
int j=
0; j<
3; j++)
st.mi[i][j] = maze[i][j];
que.push(st);
mp[s] =
1;
while(!que.empty())
{
tmp = que.front();
que.pop();
for(
int i=
0; i<
4; i++)
{
ne = tmp;
ne.x = tmp.x + xx[i];
ne.y = tmp.y + yy[i];
ne.step = tmp.step +
1;
if(ne.x<
0 || ne.x >=
3 || ne.y<
0 || ne.y>=
3)
continue;
ne.mi[tmp.x][tmp.y] = ne.mi[ne.x][ne.y];
ne.mi[ne.x][ne.y] =
‘
0
‘;
LL now = hash(ne.mi);
if(now == tot)
{
printf(
“
%d\n
“,ne.step);
return ;
}
if(!mp[now])
{
mp[now] =
1;
que.push(ne);
}
}
}
}
int main()
{
//
freopen(“in.txt”,”r”,stdin);
while(~scanf(
“
%s%s
“,s1,s2))
{
int x,y;
int len = strlen(s1);
for(
int i=
0; i<len; i++)
{
if(s1[i] ==
‘
.
‘)
s1[i]=
‘
0
‘,x=i/
3,y=i%
3;
}
s =
0;
for(
int i=
0; i<len; i++)
s = s *
10 + s1[i] –
‘
0
‘;
for(
int i=
0; i<len; i++)
{
if(s2[i] ==
‘
.
‘)
s2[i]=
‘
0
‘;
}
for(
int i=
0; i<len; i++)
{
maze[i/
3][i%
3] = s1[i];
}
tot =
0;
for(
int i=
0; i<len; i++)
tot = tot *
10 + s2[i] –
‘
0
‘;
bfs(x,y);
}
}
View Code