问题 B: 八数码问题--搜索树

问题 B: 八数码问题–搜索树

题目描述

在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。
给出一种初始状态S0和目标状态Sg,请找到一种最少步骤的移动方法,实现从初始状态S0到目标状态Sg的转变。
在这里插入图片描述

输入

输入测试次数t

对于每次测试,首先输入一个初始状态S0,一行九个数字,空格用0表示。然后输入一个目标状态Sg,一行九个数字,空格用0表示。

输出

只有一行,该行只有一个数字,表示从初始状态S0到目标状态Sg需要的最少移动次数(测试数据中无特殊无法到达目标状态数据)

样例输入

2
283104765
123804765
283104765
283164705

样例输出

4
1

代码

#include <iostream>
#include <queue>
#include <vector>
#include <string>
#include <cstring>
using namespace std;

struct node
{
    
    
    string chess;
    int move;
};

int s1[4]={
    
    -1,1,0,0};
int s2[4]={
    
    0,0,-1,1};

class Solution
{
    
    
public:
    node start,end;
    int num;//移动次数
    vector<node> visit;//装载已经访问过的结点
    queue<node> list;//装状态结点的队列
    void get_next(int x,int y,node temp1,int index)//将自己的子状态图塞入队列
    {
    
    
        if(x>=0&&x<=2&&y>=0&&y<=2){
    
    
            int a=x*3+y;//得到交换点的一维坐标
            char tempchar[10]={
    
    0};
            strcpy(tempchar,temp1.chess.c_str());
            char c=tempchar[index];
            tempchar[index]=tempchar[a];
            tempchar[a]=c;
            string upstring(tempchar);
            node t1;
            t1.chess=upstring;
            t1.move=temp1.move+1;
            if(!isexist(t1))//如果这个棋盘没出现过
                list.push(t1);
        }
    }
    bool isexist(node t)
    {
    
    
        for(int i=0;i<visit.size();i++)
            if(t.chess.compare(visit[i].chess)==0)return true;
        return false;
    }
    int find(string temp)
    {
    
    
        for(int i=0;i<temp.length();i++)
            if(temp[i]=='0')return i;
    }
    int Serach()
    {
    
    
        list.push(start);
        while(!list.empty()){
    
    
            if(list.front().chess.compare(end.chess)==0)//达到目标状态
                return list.front().move;
            visit.push_back(list.front());//标记已经访问过
            int index=find(list.front().chess);//一维的0的坐标
            int x=index/3,y=index%3;
            for(int i=0;i<4;i++)
                get_next(x+s1[i],y+s2[i],list.front(),index);//将自己的子状态图塞入队列
            list.pop();//移出队列
        }
    }
};

int main()
{
    
    
    int t;
    cin >> t;
    while(t--){
    
    
        Solution problem;
        cin >> problem.start.chess;
        cin >> problem.end.chess;
        problem.start.move=0;
        cout << problem.Serach() << endl;
    }
    return 0;
}

目的

一个笔记(写的有点复杂)

猜你喜欢

转载自blog.csdn.net/NP_hard/article/details/110352648