八数码问题(一) 暴力BFS + STL

八数码问题是一个经典的人工智能问题。具体问题不累述了。

思路:由于存在多组测试数据,可以考虑“打表法“。所谓打表法,即枚举所有的初始情况,记录其到达终点的路径。而在这个题目中,顺序打表会调用很多次BFS,所以我们采用逆序打表,只要调用一次BFS。

代码如下:

 1 /*************map存路径,set判重,string存状态*****************/
 2 /*********************暴力广搜 + STL **************************/
 3 #include<stdio.h>
 4 #include<iostream>
 5 #include<queue>
 6 #include<map>
 7 #include<set>
 8 #include<algorithm>
 9 #include<sstream>
10 using namespace std;
11 map<string, string>slu;
12 set<string>visited;
13 int dir[4][2] = { {-1,0},{1,0},{0,1},{0,-1} };
14 string base = "udrl";
15 char input[1000];
16 struct node {
17     string sta;
18     string path;
19     int pos;                //x所在的位置
20     node(string stas, string paths, int poss) {
21         sta = stas;
22         path = paths;
23         pos = poss;
24     }
25 };
26 bool check(int x, int y)
27 {
28     if (x >= 0 && x < 3 && y >= 0 && y < 3)
29         return true;
30     else
31         return false;
32 }
33 void prv_bfs()
34 {
35     queue<node>q;
36     set<string>v;
37     q.push(node("12345678x", "", 8));        //从目标状态往回扩展
38     slu["12345678x"] = " ";
39     v.insert("12345678X");
40     while (!q.empty())
41     {
42         struct node h = q.front();
43         q.pop();
44     
45         int a =  h.pos / 3;
46         int b = h.pos % 3;            //得到x的坐标
47         for (int i = 0; i < 4; i++)
48         {
49             int x = a + dir[i][0];
50             int y = b + dir[i][1];
51             int pos = 3 * x + y;
52             if (!check(x, y))
53                 continue;
54             swap(h.sta[h.pos], h.sta[pos]);
55             if (slu.find(h.sta) != slu.end())
56             {
57                 swap(h.sta[h.pos], h.sta[pos]);
58                 continue;
59             }
60             q.push(node(h.sta, h.path + base[i], pos));
61             slu[h.sta] = h.path + base[i];
62             v.insert(h.sta);
63             swap(h.sta[h.pos], h.sta[pos]);
64         }
65     }
66 }
67 int main()
68 {
69     prv_bfs();
70     while (~scanf("%s", input))
71     {
72         string line = "";
73         line = line + input[0];
74         for (int i = 1; i <= 8; i++)
75         {
76             scanf("%s", input);
77             line = line + input[0];
78         }
79         if (slu[line] == "") cout << "unsolvable" << endl;
80         else cout << slu[line] << endl;
81     }
82 
83     return 0;
84 
85 }

当然,这一题还有很多很好的方法,我会慢慢补充。

新手入门,希望多多交流!

猜你喜欢

转载自www.cnblogs.com/lfri/p/9090724.html