迷宫问题——回溯法解


题目描述



迷宫是一个二维矩阵,其中1为墙,0为路,入口在第一列,出口在最后一列。

要求从入口开始,从出口结束,按照 上,下,左,右 的顺序来搜索路径.


输入



第一行输入迷宫大小N

第二行输入入口坐标

接下来n行输入完整迷宫


输出



输出完整棋盘,所有解法,走过的路用6表示。


样例输入


 8
 0 7
 1 1 1 1 1 1 1 1
 1 0 1 1 0 0 0 0
 1 0 1 0 0 1 0 1
 1 1 0 0 1 0 1 1
 1 0 0 1 0 0 0 1
 1 0 0 0 0 1 1 1
 1 0 1 0 0 1 0 1
 0 0 1 0 0 0 1 1
 1 1 1 1 0 0 0 1
 1 1 1 1 1 1 1 1 

样例输出


 1 1 1 1 1 1 1 1
 1 0 1 1 6 6 6 6
 1 0 1 6 6 1 0 1
 1 1 6 6 1 0 1 1
 1 6 6 1 0 0 0 1
 1 6 0 0 0 1 1 1
 1 6 1 0 0 1 0 1
 6 6 1 0 0 0 1 1
 1 1 1 1 0 0 0 1
 1 1 1 1 1 1 1 1

实现代码


#include <stdio.h>
#define N 19 //整个迷宫大小(包括最外层墙壁)

char Maze[N][N] = {
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
    {1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0},
    {1,1,1,0,1,1,1,0,1,0,1,1,1,1,1,0,1,1,1},
    {1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1},
    {1,1,1,0,1,0,1,0,1,1,1,1,1,0,1,1,1,1,1},
    {1,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,0,0,1},
    {1,0,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1},
    {1,0,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1},
    {1,0,1,0,0,0,0,0,0,0,1,0,1,0,1,0,0,0,1},
    {1,0,1,0,1,1,1,0,0,0,1,0,1,0,1,0,1,0,1},
    {1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,1,0,1},
    {1,0,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1},
    {1,0,1,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,1},
    {1,0,1,0,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1},
    {1,0,1,0,1,0,0,0,1,0,0,0,1,0,1,0,1,0,1},
    {1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,0,1,0,1},
    {0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1},
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
};
char step[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};   //定义四个方向
int count = 0;

char Check(char i, char j)  //判断下一步是不是通路
{
    if(i >= 0 && i<=18 && j >= 0 && j <= 18)
    {
        if(0 == Maze[i][j])
        {
            return 1;
        }
    }
    return 0;
}

void Display(void)
{
    char i, j;

    for(i=0; i<N; ++i)
    {
        for(j=0; j<N; ++j)
        {
            printf("%d", Maze[i][j]);
        }
        printf("\n");
    }
}

void Find(char ci, char cj)
{
    char n;
    if((N-1) == cj) //这个边界设置得比较粗糙,到N-1这个下标就算终点,没想到什么好的办法
    {
        Maze[ci][cj] = 6;   //终点的最后一个6
        printf("解法%d(Enter回车查看下一解法):\n", ++count);
        Display();
        getchar();
        Maze[ci][cj] = 0;
    }
    else
    {
        for(n=0; n<4; ++n)
        {
            if(Check(ci+step[n][0], cj+step[n][1])) //依然用Check实现判断:是否可以在某个方向走下一步
            {
                Maze[ci][cj] = 6;   //6表示走过的路
                Find(ci+step[n][0], cj+step[n][1]);
                Maze[ci][cj] = 0;   //传统回溯方法
            }
        }
    }
}

int main(void)
{
    printf("\t迷宫问题(1 墙壁 0 道路 6 解法)\n\n");
    printf("原迷宫(Enter回车查看解法):\n");
    Display();
    getchar();

    //(17, 0)为起点
    Find(17, 0);

    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-09 00:56:26

迷宫问题——回溯法解的相关文章

回溯法解背包问题分析

先亮出题目: 一,背包问题 及 回溯法解其问题的伪代码 二,赋值后的具体实例 三,如何看懂伪代码 (1)真正了解回溯法的核心思想 我总结的回溯法解题步骤: <1>先找出第一个解 <2>回溯 (2)回溯法核心思想 + 伪代码 + 图9-5 树结构来分析 四,伪代码代入值解析 核心:先找到第一个解,再回溯. cw=0;//背包当前重量 初始值 cp=0;//背包当前价值 初始值 k=1;//第一个物品 n=8;//共8个物品 W=110 第一步:得出第1个可行解: (1)k=1 k=1

八皇后问题-回溯法解

八皇后问题:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. int g_number = 0;? //多少种摆放方法?void EightQueen(){? ?const int queens = 8;? //棋盘大小?? ?int ColumnIndex[queens];? //列索引?//遍历行? ?for(int i = 0; i < queens; ++ i)?? ? ? ?ColumnIndex[i] = i;

暴力回溯法 解八皇后

国际象棋 八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. public class _8Queen { //回溯法,暴力解8皇后 private static int ways = 0; //返回解法个数 public static int f8queen() { int[][] board = new int

每天刷个算法题20160519:回溯法解八皇后

版权所有.所有权利保留. 欢迎转载,转载时请注明出处: http://blog.csdn.net/xiaofei_it/article/details/51502622 为了防止思维僵化,每天刷个算法题.已经刷了几天了,现在发点代码. 我已经建了一个开源项目,每天的题目都在里面: https://github.com/Xiaofei-it/Algorithms 绝大部分算法都是我自己写的,没有参考网上通用代码.读者可能会觉得有的代码晦涩难懂,因为那是我自己的理解. 最近几天都是在写一些原来的东西

回溯法解数独题

近段时间用到回溯算法的地方比较多,对算法的理解也有深入.今天偶然发现一张照片,是高中时未做完的一道数独题.当时用的是"候选余数法",之后由于太麻烦,就没有做完.不过当时截图保存了,今天突然看到.那时候刚学完C语言,对汉诺塔递归都不是太理解,所以就一直拖到现在. 用C++做的,代码如下 #include<iostream> usingnamespace std;   intsudoku[9][9]={0};   //判断填在空白位置的数字在行.列上是否符合要求 boolJud

回溯法解0-1背包问题(王晓东算法例题)

给定n种物品和一背包.物品i的重量是wi,其价值为vi,背包的容量为C.问应如何选择装入背包的物品,使得装入背包中物品的总价值最大? 整个解的空间相当于一个二叉树,左边是0,代表不取这个物品,右边是1,代表取这个物品,然后进行dfs,回溯的时候修改. 注意,这里应该有两个剪枝,我这里只写了一个. #include<iostream> #include<string> #include<cstring> using namespace std; int n,TotCap,

noj算法 迷宫问题 回溯法

描述: 给一个20×20的迷宫.起点坐标和终点坐标,问从起点是否能到达终点. 输入: 多个测例.输入的第一行是一个整数n,表示测例的个数.接下来是n个测例,每个测例占21行,第一行四个整数x1,y1,x2,y2是起止点的位置(坐标从零开始),(x1,y1)是起点,(x2,y2)是终点.下面20行每行20个字符,'.'表示空格:'X'表示墙. 输出: 每个测例的输出占一行,输出Yes或No. 输入样例: 20 0 19 19....................XXXXXXXXXXXXXXXXX

回溯法求装载问题

1.回溯法 (1)描述:回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法.  (2)原理: 回溯法在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树.算法搜索至解空间树的任意一点时,先判断该结点是否包含问题的解.如果肯定不包含,则跳过对该结点为根的子树的搜索,逐层向其祖先结点回溯:否则,进入该子树,继续按深度优先策略搜索. 回溯法的基本做法是搜索,或是一种组织得井井有条的,

回溯法之符号三角形问题

/*回溯法解符号三角形问题 问题描述: 如下图是由14个“+”和14个“-”组成的符号三角形, 2个同号下面都是“+”,2个异号下面都是“-”. - + + - + + + - + - - + + - - + - + + - - - - + + - + - 在一般情况下,符号三角形的第一行有n个符号, 符号三角形问题要求对于给定的n, 计算有多少个不同的符号三角形,使其所含的“+”和“-”的个数相同. 解题思路: 1.不断改变第一行每个符号,搜索符合条件的解,可以使用递归回溯 为了便于运算,设+