IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> (新版)SJTU-OJ-1029. 深度优先搜索问题 -> 正文阅读

[数据结构与算法](新版)SJTU-OJ-1029. 深度优先搜索问题

题目描述

有一个6*6的棋盘,每个棋盘上都有一个数值,现在又一个起始位置和终止位置,请找出一个从起始位置到终止位置代价最小的路径:

  1. 只能沿上下左右四个方向移动
  2. 总代价是没走一步的代价之和
  3. 每步(从a,b到c,d)的代价是c,d上的值与其在a,b上的状态的乘积
  4. 初始状态为1

每走一步,状态按如下公式变化:(走这步的代价%4)+1。

输入格式

第一行有一个正整数n,表示有n组数据。

每组数据一开始为6*6的矩阵,矩阵的值为大于等于1小于等于10的值,然后四个整数表示起始坐标和终止坐标。

输出格式

输出最小代价

样例输入

1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
0 0 5 5

样例输出

23

数据范围

(无)

深度优先搜索 DFS

?????? DFS【Deep First Search】,利用递归函数,一头往一个方向撞下去,不撞到南墙不死心那种,一旦有障碍就缩回去,调头,换方向。
??????关键:要有一个bool数组,记录已经走过的路,而且注意!在退回来的时候要修改bool数组的内容。

		book[ntx][nty] = 1;				// 要去坐标为(ntx,nty)的位置,数组上标记一下
       	thiscost = testmap[ntx][nty] * state;
        dfs(ntx, nty, thiscost % 4 + 1, cost + thiscost);
        book[ntx][nty] = 0;				// 函数运行完了,原路退回,bool数据记得恢复

??????问题:为什么要不断改这个 bool 数组的值?
??????解答:DFS本质是尝试,一个劲的尝试,比如我规定顺序{东,南,西,北},好,那么从起点开始,我就向东,看看能不能走,可以的话就向东,然后检测有没有到终点,没有到终点,继续递归,再看看能不能往东走,不行就尝试下一个,向南走,然后检测有没有到终点,没有到就继续尝试看能不能向东走……(人类的本质就是复读,你觉得呢)
??????一旦到了终点,好耶,找到一条路,然后呢,怎么办比较一下看看和已找到的路相比哪个更近一些,如果发现更近的那就要更新结果。然后呢,然后要退回去,回到哪,回到起点,当然函数不会调头,只会默默的结束运行,每一个内层函数结束后,运行的第一个语句是什么?book[ntx][nty] = 0; 之前标记为已经走过的路,现在撤销标记,这是DFS的关键核心!
??????问题:如何优化DFS?
??????解答:剪支!见下,如果在走的途中花费已经超过之前找到的答案,直接停止运行不用找了,没有浪费时间的必要。

 if (cost > result)
        return;

题目解答

??????还是回归递归函数的本质,模拟一个过程,同理我们这个题目也是,模拟的就是走一步的过程,递归结束的条件是什么?到终点。递归传递的参数是什么?坐标,状态,花费的代价。

#include <iostream>
#include <string.h>
#include <limits.h>
using namespace std;
int testmap[6][6];
int book[6][6] = {0};
int stx, sty, edx, edy;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
int result;

// 注意,每次调用dfs函数前要result = INT_MAX;
void dfs(int nx, int ny, int state, int cost)
{
    int ntx, nty,thiscost;
    if (nx == edx && ny == edy)
    {
        if (cost < result)
        {
            result = cost;
        }
        return;
    }

    if (cost > result)
        return;

    for (int i = 0; i < 4; i++)
    {
        ntx = nx + dx[i];
        nty = ny + dy[i];
        if (ntx >= 6 || ntx < 0 || nty >= 6 || nty < 0)
        {
            continue;
        }
        if (book[ntx][nty] == 0)
        {
            book[ntx][nty] = 1;
            thiscost = testmap[ntx][nty] * state;
            dfs(ntx, nty, thiscost % 4 + 1, cost + thiscost);
            book[ntx][nty] = 0;
        }
    }
}

int main()
{
    int n;
    cin >> n;

    // 下面开始循环n次
    while(n--)
    {
        memset(book,0,sizeof(book));
        result = INT_MAX;
        for (int i = 0; i < 6; i++)
        {
            for (int j = 0; j < 6; j++)
            {
                cin >> testmap[i][j];
            }
        }
        cin >> stx >> sty >> edx >> edy;
        dfs(stx, sty, 1, 0);
        cout << result;
        // 上面需要循环n次
    }
    system("pause");
    return 0;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-07-27 16:29:50  更:2021-07-27 16:31:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/8 3:42:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码