zoukankan      html  css  js  c++  java
  • 八数码问题(一) 暴力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 }

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

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

  • 相关阅读:
    【转】shell处理mysql增删改查
    【转】jenkins_pipeline语法详解
    【原】Jenkins pipeline中资料总结
    【转】使用普通用户执行docker
    【原】linux两台服务器之间免密登录方法
    【原】mac电脑常用快捷建
    【原】Docker学习_Docker上传镜像至docker hub(4)
    项目实战---模拟亿邦动力网
    vue-组件之间的通信:
    vue-为什么子组件中的data选项必须是函数?
  • 原文地址:https://www.cnblogs.com/lfri/p/9090724.html
Copyright © 2011-2022 走看看