八數碼問題 (stl bfs)

問題 J: 八數碼問題

時間限制: 5 Sec  內存限制: 128 MB
提交: 143  解決: 80
[提交][狀態][討論版]

題目描述

八數碼問題,即在一個3×3的矩陣中有8個數(1至8)和一個空格,現在要你從一個狀態轉換到另一個狀態,每次只能移動與空格相鄰的一個數字到空格當中,問題是要你求從初始狀態移動到目標狀態所需的最少步數。如下圖所示。

1

2

3

 

1

2

3

8

0

4

 

7

8

4

7

6

5

 

0

6

5

                   初始狀態                                 目標狀態

如上圖所示的數據以矩陣形式給出。現在給出分別代表初始狀態和目標狀態的兩個3*3的矩陣,請給出兩個矩陣相互轉化的最少步數。

輸入

第1行-第3行:3個用空格分隔的整數,代表初始狀態相應位置的數字,0代表空格
第4行-第6行:3個用空格分隔的整數,代表終止狀態相應位置的數字,0代表空格

輸出

第1行:一個整數,最小轉換步數,如不能到相互轉化則輸出"Impossible"

樣例輸入

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

樣例輸出

2

提示

#include <iostream>
#include <queue>
#include <cstdio>
#include <set>
#include <cstring>
using namespace std;
typedef int state[9];
state st[1000010],end1;     //st相當於二維數組
int dis[1000010];
set <int> ly;               //set維護st
void table() {
    ly.clear();
}
int try_insert(int a) {
    int s=0;
    for(int j=0; j<9; j++)
        s=s*10+st[a][j];
    if(ly.count(s)) return 0;             //利用stl去重,是最容易實現的
    ly.insert(s);
    return 1;
}
const int dir[4][2]= {{1,0},{0,1},{-1,0},{0,-1}};
int bfs() {


    table();
    int fr=1,re=2;
    while(fr<re) {
        state& s =st[fr];
        if(!memcmp(s,end1,sizeof(s))) return fr;
        int z;
        for(z=0; z<9; z++) if(!s[z]) break;
        int x=z/3;                          //轉爲二維空間的行
        int y=z%3;                       // 轉爲二維空間的列
        for(int i=0; i<4; i++) {
            int newx=x+dir[i][0];
            int newy=y+dir[i][1];
            int newz=newx*3+newy;
            if(newx>=0 && newx <3 && newy>=0 && newy<3) {
                state &t=st[re];
                memcpy(t,s,sizeof(t));
                t[newz]=s[z];
                t[z]=s[newz];
                dis[re]=dis[fr]+1;
                if(try_insert(re)) re++;   //如果沒有重複出現,尾指針re向後移位。如果重複,則仍停在原來的位置。
            }


        }


        fr++;


    }
  return 0;
}
int main() {
    int ans=0;
    for(int i=0; i<9; i++) {
        scanf("%d",&st[1][i]);      
    }
    for(int i=0; i<9; i++) {
        scanf("%d",&end1[i]);    //最終目標
    }
    ans=bfs();
    if(ans>0) printf("%d\n",dis[ans]);
    else
        printf("Impossible\n");
    }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章