递归,搜索,回溯,最优路径(线段)

基本信息 内存:520kB 时间:0ms 语言:G++

题目链接http://bailian.openjudge.cn/practice/solution/4779752/

解题报告:

1、输入表格时,由于这里有空格,不能用scanf函数。

2、gets(board[i]+1) 不要把第一列刷去。

3、回溯mark[y][x]=false;这里在Search玩后,一定要将mark[y][x]改为false.否则下一次的搜索将不会访问到这个点。

4、方向最好用数组形式表示。

5、最重要的一点是:这里的一条线段才为一步,因此,face于是记录方向。

#include <stdio.h>
#include <string.h>

#define MAXIN 75
#define INF 0x3f3f3f3f

#define IN_BOARD ((x > -1) && (x < w + 2) && (y>-1) && (y<h + 2))    //x,y在边界内
#define BLANK_POINT ((board[y][x] == ‘ ‘) && (mark[y][x] == false))    //该点为空
#define DESTINATION ((x ==end_x) && (y ==end_y) && (board[y][x] == ‘X‘))    //达到目的地

char board[MAXIN + 2][MAXIN + 2];//定义矩阵
int minstep, w, h;
int to[4][2] = { { 0,1 },{ 0,-1 },{ 1,0 },{ -1,0 } };
bool mark[MAXIN + 2][MAXIN + 2];

void Search(int now_x, int now_y, int end_x, int end_y, int step, int face)
{
    if (step > minstep)    return;

    if (now_x == end_x && now_y == end_y)
        {
            if(minstep>step)
            minstep = step;
            return;
        }

    for (int i = 0; i < 4; i++)
    {
        int x = now_x + to[i][0];
        int y = now_y + to[i][1];
        if (IN_BOARD && (BLANK_POINT || DESTINATION))
        {
            mark[y][x] = true;
            if (face == i) Search(x, y, end_x, end_y, step, i);
            else Search(x, y, end_x, end_y, step + 1, i);
            mark[y][x] = false;
        }
    }
}

int main()
{
    int BoardNum = 0;
    while (scanf("%d%d", &w, &h))
    {
        getchar();
        if (w == 0 && h == 0) break;
        printf("Board #%d:\n", ++BoardNum);

        for (int i = 1; i <= h; i++)
            gets(board[i]+1);

        //边界置空
        for (int i = 0; i <= w + 1; i++)
            board[0][i] = board[h + 1][i] = ‘ ‘;
        for (int i = 0; i <= h ; i++)
            board[i][0] = board[i][w + 1] = ‘ ‘;

        int begin_x, begin_y, end_x, end_y;
        int count = 0;
        while (scanf("%d%d%d%d", &begin_x, &begin_y, &end_x, &end_y) && begin_x > 0)
        {
            minstep = INF;
            memset(mark, false, sizeof(mark));

            Search(begin_x, begin_y, end_x, end_y, 0, -1);

            if (minstep < INF)
                printf("Pair %d: %d segments.\n", ++count, minstep);
            else
                printf("Pair %d: impossible.\n", ++count);
        }
        printf("\n");
    }
    return 0;
}
时间: 2024-10-17 01:58:40

递归,搜索,回溯,最优路径(线段)的相关文章

素数环(递归 搜索 回溯)

素数环:从1到20这20个数摆成一个环,要求相邻的两个数的和是一个素数. 分析:首先设有20个空位,填进20个数,可以填数的条件是这个数在之前没有出现过,并且与它的前一个数的和是 一个素数:注意第二十个数时还要判断与第一个数的和是否是一个素数.若满足条件,填数,否则填下一个数: 代码如下: #include<iostream>#include<cstdio>#include<cstdlib>#include<cmath>using namespace std

路网最优路径算法之一分层搜索

1 背景 前面介绍了关于双向及启发式的搜索,它们均可以实现了效率的倍增.但是应用到长距离(例如武汉——杭州大于500公里)的搜索时,平均效率存在100ms级甚至s级的耗时,显然这样一个面对广大用户群的互联网服务引擎效率是不可接受的,那么有没有优化的方向可以实现数量级的提升?      但人类对效率与正确的极致追求也是不止境的.关于双向及启发式搜索,它们的优化初衷均是一致的:缩短搜索范围.有人想到另一个路网搜索优化的方向:稀疏搜索路网密度——分层算法. 2 分层算法 假设有个长距离路径搜索的cas

穷举递归和回溯算法终结篇

穷举递归和回溯算法 在一般的递归函数中,如二分查找.反转文件等,在每个决策点只需要调用一个递归(比如在二分查找,在每个节点我们只需要选择递归左子树或者右子树),在这样的递归调用中,递归调用形成了一个线性结构,而算法的性能取决于调用函数的栈深度.比如对于反转文件,调用栈的深度等于文件的大小:再比如二分查找,递归深度为O(nlogn),这两类递归调用都非常高效. 现在考虑子集问题或者全排列问题,在每一个决策点我们不在只是选择一个分支进行递归调用,而是要尝试所有的分支进行递归调用.在每一个决策点有多种

LeetCode 31:递归、回溯、八皇后、全排列一篇文章全讲清楚

本文始发于个人公众号:TechFlow,原创不易,求个关注 今天我们讲的是LeetCode的31题,这是一道非常经典的问题,经常会在面试当中遇到.在今天的文章当中除了关于题目的分析和解答之外,我们还会详细解读深度优先搜索和回溯算法,感兴趣的同学不容错过. 链接 Next Permutation 难度 Medium 描述 实现C++当中经典的库函数next permutation,即下一个排列.如果把数组当中的元素看成字典序的话,那下一个排列即是字典序比当前增加1的排列.如果已经是字典序最大的情况

蚁群算法求解迷宫最优路径问题

本段程序的基本思想是利用蚁群算法中的蚁周模型,来对全局的迷宫图进行信息素的跟新 和为每一只蚂蚁选择下一个方格. 一共会进行RcMax = 2000轮模拟(理论上模拟的次数越多结果 会越接近真实值),而在每一轮中会排除 M = 10只蚂蚁进行探路.同时在算法的回溯思想上采用的 是栈的数据结构来实现的.当栈最终为空时则表示无解.但同时这段程序的一缺点就是:由于我没在 算法中对每一轮的每只探路蚂蚁采用多线程的模式,所以整体的运行效率还不是很高.如读者有好的 思想或建议,请留言. #include<io

最优路径问题

package 数阵中的最优路径; import java.util.Scanner; public class Main { /** * 数值三角形中的最大路径 * 随机产生一个n行的点数值三角形(第k行有k个点,每个点都带有一个正整数,)寻找从顶点开始每一步可沿着左或者右向下的至底部的一条路径, * 使得该路径的和最大. * * 数值三角形中的最大路径的搜索 * 应用动态规划,采用逆推法从低向上逐行反推 * 随机产生的点数值三角形存储在一个二维数组中,同时赋值给b(n,n),这里的数组b(i

递归,回溯,DFS,BFS的理解和模板【摘】

递归:就是出现这种情况的代码: (或者说是用到了栈) 解答树角度:在dfs遍历一棵解答树 优点:结构简洁缺点:效率低,可能栈溢出 递归的一般结构: 1 void f() { 2 if(符合边界条件) { 3 /////// 4 return; 5 } 6 7 //某种形式的调用 8 f(); 9 } 回溯:递归的一种,或者说是通过递归这种代码结构来实现回溯这个目的.回溯法可以被认为是一个有过剪枝的DFS过程.解答树角度:带回溯的dfs遍历一棵解答树回溯的一般结构: 1 void dfs(int

这是递归和回溯的算法 是abcd&#39;的排列可能

#include<stdio.h>#include<iomanip>#include<iostream>using namespace std;bool b[10]={0};int a[10]={0};int print(){ for (int i=1;i<=4;i++) printf("%c ",a[i]); printf("\n");} int dosomething(int z){ int mm; for ( mm=1

路网最优路径算法总结

前段时间,关于路网最优路径算法的专题我做了一次内部分享,感兴趣的朋友可以进行查看与下载,     链接如下: http://files.cnblogs.com/files/gisorange/%E8%B7%AF%E7%BD%91%E6%9C%80%E4%BC%98%E8%B7%AF%E5%BE%84%E7%AE%97%E6%B3%95%E6%A6%82%E8%BF%B0-2015-9-22.pdf

【C#】递归搜索指定目录下的指定项目(文件或目录)

先别急着喷,请听我解释. 诚然可以使用现成的Directory类下的GetFiles.GetDirectories.GetFileSystemEntries这几个方法实现同样的功能,但请相信我不是蛋疼,原因是这几个方法在遇上[System Volume Information]这种目录时,极有可能会给你个拒绝访问的异常,想跳过都不行.所以没办法,重新实现了一下. 实现说明: - 仍然是基于对Directory类的几个方法的封装进行实现,只是没有使用它们的searchPattern和searchO