蓝桥杯—九宫重排(bfs + hash)
历届试题 九宫重排
时间限制:1.0s 内存限制:256.0MB
问题描述
如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。
我们把第一个图的局面记为:12345678.
把第二个图的局面记为:123.46758
显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
我们把第一个图的局面记为:12345678.
把第二个图的局面记为:123.46758
显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
输入格式
输入第一行包含九宫的初态,第二行包含九宫的终态。
输出格式
输出最少的步数,如果不存在方案,则输出-1。
样例输入
12345678.
123.46758
123.46758
样例输出
3
样例输入
13524678.
46758123.
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);
}
}
#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);
}
}