zoukankan      html  css  js  c++  java
  • Problem C: 【宽搜入门】8数码难题

    Description

    初始状态的步数就算1,哈哈

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

    参考链接:问题 C: 【宽搜入门】8数码难题

    最终AC代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    int final[3][3];
    int dir[4][2]={{0, -1},{-1, 0},{0, 1},{1, 0}}; //方向 
    struct Node{
        int x, y, step, pdir, M[3][3]; //pdir记录上一次的方向 M当前的矩阵状态 
    }now, nex;
    bool judge(){
        int i, j;
        for(i=0; i<3; i++){
            for(j=0; j<3; j++) if(nex.M[i][j] != final[i][j]) return false;
        }
        return true;
    }
    int BFS(){
        int i, t, ti, tj;
        now.step = 1;
        now.pdir = 8; //初始化一个方向 注意范围不能是-2至6! 
        queue<Node> q;
        q.push(now);
        while(!q.empty()){
            now = q.front();
            q.pop();
            for(i=0; i<4; i++){
                if(abs(i-now.pdir) == 2) continue; //表明又要回到上一个状态 
                nex.x = now.x + dir[i][0];
                nex.y = now.y + dir[i][1];
                if(nex.x<0 || nex.x>2 || nex.y<0 || nex.y>2) continue; //位置不合理 
                nex.pdir = i; //记录方向
                nex.step = now.step + 1; //步长加1 
                for(ti=0; ti<3; ti++){ //复制矩阵 
                    for(tj=0; tj<3; tj++) nex.M[ti][tj] = now.M[ti][tj];
                }
                //表示走一步 达到下一个状态 
                t = nex.M[now.x][now.y];
                nex.M[now.x][now.y] = nex.M[nex.x][nex.y];
                nex.M[nex.x][nex.y] = t;
                if(judge()) return nex.step;
                q.push(nex);
            }
        }
        return -1; //别忘了遍历完,找不到的情况
    }
    int main(){
        int i, j;
        for(i=0; i<3; i++){
            for(j=0; j<3; j++){
                scanf("%d", &now.M[i][j]);
                if(now.M[i][j] == 0) now.x=i, now.y=j;
            }
        }
        for(i=0; i<3; i++){
            for(j=0; j<3; j++) scanf("%d", &final[i][j]);
        }
        printf("%d
    ", BFS());
        return 0;
    }

    注意:题目描述得比较简单,因此很多重要信息没有给出:比如,可能有不存在的情况需要返回-1,输入的0表示图片中的空格。

    总结:自己在写的时候,是直接再矩阵中改变状态,因此到后面就写不去。然后,参考别人的代码,发现采用的方法是:每走一步产生的状态都存在一个数组中。但是,这里要注意,必须记录该状态是从哪个方向转化的,避免此次选择的方向会再次回到之前的状态。

    通过这个题,对BFS()算法有了一点新领悟:while循环每次遍历过程中,只要满足某个条件就会有新的元素入队,直到找到答案或者搜索完。这里,找答案的过程,其实是多路进行的,即在找到答案前,是有一些不可避免的“冗余操作”。我自己的理解是,既然不知道哪条路径可以找到答案,那么我就把第一层所有情况遍历完后,再进入到第二层,并依此类推。而DFS()搜索则是典型的“不撞南墙不回头”。

  • 相关阅读:
    Linux中的文件类型
    Verilog定义变量类型为signed的几种情况
    verilog中>>>和>>的区别
    Linux中的快捷键
    Linux中的常用命令
    CVS版本控制
    [GitHub] fatal: unable to access 'https://github.com/': Failed to connect to github.com port 443: Operation timed out
    如何在手机(安卓)中搜索照片
    JS+CSS+HTML 前端开发(二)
    JS+CSS+HTML 前端开发(一)
  • 原文地址:https://www.cnblogs.com/heyour/p/12672651.html
Copyright © 2011-2022 走看看