8数码问题

Problem:

八数码问题也称为九宫问题。在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同。棋盘上还有一个空格,与空格相邻的棋子可以移到空格中。要求解决的问题是:给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤。

输入:第一个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

Solution 1:

 

#include
#include
#include
#include
#include
#include
#include
using namespace std;
struct node {
    int x, y;
    int step;
    int T[3][3];
   
}S,Node;
int A[3][3];
int B[3][3];
int X[4] = { 0,0,1,-1 };
int Y[4] = { 1,-1,0,0 };

bool test1(int x, int y) {
    if (x > 2 || x < 0 || y>2 || y < 0) return false;
    return true;
}

bool test2(int A[3][3]) {
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            if (A[i][j] != B[i][j])
                return false;
        }
    }
    return true;
}

int BFS() {
    queue q;
    q.push(S);
    while (!q.empty()) {
        node top = q.front();
        q.pop();
        if (test2(top.T))
            return top.step;
        for (int i = 0; i < 4; i++) {
            int newx = top.x + X[i];
            int newy = top.y + Y[i];
          
           if (test1(newx, newy)) {
                for (int i = 0; i < 3; i++) {
                    for (int j = 0; j < 3; j++) {
                        Node.T[i][j] = top.T[i][j];
                    }
                }
                Node.x = newx, Node.y = newy;
               
                Node.step = top.step + 1;
                Node.T[top.x][top.y] = Node.T[newx][newy];
                Node.T[newx][newy] = 0;
                q.push(Node);

            }


        }
    }
    return -1;
}

int main() {
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            cin>>S.T[i][j];
            if (S.T[i][j] == 0){
                S.x = i, S.y = j;
                S.step = 1;
                
             }
        }
    }
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            cin >> B[i][j];
        }
    }
 
    int STEP= BFS();
    cout << STEP << endl;
}

Solution 2:

然后修改了一下,不做重复行为,然后耗时显著减少

#include
#include
#include
#include
#include
#include
#include
using namespace std;
struct node {
    int x, y;
    int step;
    int T[3][3];
    int last[2];       //增加了一个存储上一步坐标的结构
}S,Node;
int A[3][3];
int B[3][3];
int X[4] = { 0,0,1,-1 };
int Y[4] = { 1,-1,0,0 };

bool test1(int x, int y) {
    if (x > 2 || x < 0 || y>2 || y < 0) return false;
    return true;
}

bool test2(int A[3][3]) {
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            if (A[i][j] != B[i][j])
                return false;
        }
    }
    return true;
}

int BFS() {
    queue q;
    q.push(S);
    while (!q.empty()) {
        node top = q.front();
        q.pop();
        if (test2(top.T))
            return top.step;
        for (int i = 0; i < 4; i++) {
            int newx = top.x + X[i];
            int newy = top.y + Y[i];
            if (newx == top.last[0] && newy == top.last[1])
                ;                   // 检验是否是重复步骤
            else if (test1(newx, newy)) {
                for (int i = 0; i < 3; i++) {
                    for (int j = 0; j < 3; j++) {
                        Node.T[i][j] = top.T[i][j];
                    }
                }
                Node.x = newx, Node.y = newy;
                Node.last[0] = top.x, Node.last[1] = top.y;
                Node.step = top.step + 1;
                Node.T[top.x][top.y] = Node.T[newx][newy];
                Node.T[newx][newy] = 0;
                q.push(Node);

            }


        }
    }
    return -1;
}

int main() {
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            cin>>S.T[i][j];
            if (S.T[i][j] == 0){
                S.x = i, S.y = j;
                S.step = 1;
                S.last[0] = i, S.last[1] = j;
             }
        }
    }
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            cin >> B[i][j];
        }
    }
 
    int STEP= BFS();
    cout << STEP << endl;      // 直接cout<

 

你可能感兴趣的:(程序人生)