蓝桥杯—九宫重排(bfs + hash)

  历届试题 九宫重排   时间限制:1.0s   内存限制:256.0MB         问题描述   如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。

《蓝桥杯—九宫重排(bfs + hash)》
《蓝桥杯—九宫重排(bfs + hash)》

  我们把第一个图的局面记为:12345678.

  把第二个图的局面记为:123.46758

  显然是按从上到下,从左到右的顺序记录数字,空格记为句点。

  本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。 输入格式   输入第一行包含九宫的初态,第二行包含九宫的终态。 输出格式   输出最少的步数,如果不存在方案,则输出-1。 样例输入 12345678.

123.46758 样例输出 3 样例输入 13524678.

46758123. 样例输出 22        
code:  
《蓝桥杯—九宫重排(bfs + hash)》
《蓝桥杯—九宫重排(bfs + hash)》 #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  

    原文作者:Doli
    原文地址: https://www.cnblogs.com/ACMDoli/articles/4392996.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞