【算法笔记第8.2节-BFS 】问题 C: 【宽搜入门】8数码难题

题目描述

初始状态的步数就算1,哈哈

输入:第一个3*3的矩阵是原始状态,第二个3*3的矩阵是目标状态。
输出:移动所用最少的步数

Input

2 8 3
1 6 4
7 0 5
1 2 3
8 0 4
7 6 5

Output

6

这个题目没有把条件说清楚,完整题目描述:

在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。
感觉这小节的BFS比上节的dfs难点。

参考大佬代码:https://blog.csdn.net/u012283461/article/details/79078653#commentBox

#include
#include
#include
#include
using namespace std;
/*
sscanf(str, "%d", &n) string + scanf将字符数组str中的内容以"%d"的格式写到n中(从左到右)
sprintf(str, "%d", n) string + printf 把n以"%d"格式写到str字符数组中(从右向左)
*/
int n, des=0;
map m;
int dis[9][4]=//0出现在0,1,2,3,4,5,6,7,8位置后可以交换的位置,-1代表不可交换,0代表可与第一个数交换
{
    {-1,-1,3,1},//0出现在0位置可与1位置和3位置交换
    {-1,0,4,2},
    {-1,1,5,-1},
    {0,-1,6,4},
    {1,3,7,5},
    {2,4,8,-1},
    {3,-1,-1,7},
    {4,6,-1,8},
    {5,7,-1,-1},
};
void swap(char *c, int a, int b)//交换字符串的两个位置
{
    char t=c[a];
    c[a]=c[b];
    c[b]=t;
}
struct Information
{
    int pl;
    int id;
    int step;
};
int bfs(int n, int p)
{
    queue q;
    m[n] = 1;
    Information t;
    t.pl = n;
    t.id = p;
    t.step = 1;
    q.push(t);
    while(!q.empty())
    {
        Information top = q.front();
        q.pop();
        char cur[10];//用于保存当前状态的字符串
        int pos = top.id, temp;//当前状态中0的位置
        //这里不明白为啥要加%09d
        sprintf(cur,"%09d",top.pl);//string + printf 把n以"%d"格式写到str字符数组中(从右向左)
        for(int i=0; i<4; i++)
        {
            int swapTo = dis[pos][i];//将要和那个位置交换
            if(swapTo!=-1)//-1为不可达
            {
                swap(cur, pos, swapTo);//交换得到新状态 
                //string + scanf将字符数组cur中的内容以"%d"的格式写到n中(从左到右)
                sscanf(cur,"%d",&temp);//新位置转换为int保存到temp 
                if(temp==des)
                    return top.step+1;
                if(m.count(temp)==0)//使用count,返回的是被查找元素的个数
                {
                   t.pl = temp;
                   t.id = swapTo;
                   t.step = top.step+1;
                   m[temp] = 1;
                   q.push(t);
                }
                 swap(cur, pos, swapTo);//一个新状态处理好了,将0交换回来
            }
        }
    }
}
int main()
{
    n = 0;
    des = 0;
    int m, cnt = 0,index;
    for(int i=0; i<9; i++)//初始状态
    {
        scanf("%d",&m);
        if(m==0)//查找初始状态0的位置
            index = i;
        n = n*10 + m;
    }
    for(int i=0; i<9; i++)//目的状态
    {
        scanf("%d",&m);
        des = des*10+m;
    }
    if(n!=des)//初始状态不等于目的状态
        cnt = bfs(n,index);
    printf("%d\n",cnt);
    return 0;
}
/*
2 8 3
1 6 4
7 0 5
1 2 3
8 0 4
7 6 5
*/

 

你可能感兴趣的:(【算法笔记】,Codeup墓地,算法笔记)