首页 > 编程语言 >C++U5-第02课-深度优先搜索2

C++U5-第02课-深度优先搜索2

时间:2024-01-23 15:57:31浏览次数:26  
标签:02 ny U5 vis C++ nx int mp &&

学习目标

 

 迷宫地图类的深搜

 对于二维数组中一个点的行和列x,y;与周围8个方向位置的关系

[迷宫的相邻点]

 

遍历 (x,y) 的周围的四个方向,判断是否越界,无越界输出。

【参考代码】
#include <iostream>
using namespace std;

int n, m, x, y;
int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};

bool check(int x, int y){
    return x >= 1 && x <= n && y >= 1 && y <= m;
}

int main() {
    cin >> n >> m >> x >> y;
    for(int i = 0; i < 4; i++){
        int nx = x + dir[i][0];
        int ny = y + dir[i][1];
        if(check(nx,ny)) cout << nx << " " << ny << endl;
        else cout << "NA" << endl; 
    }
    return 0;
}
View Code

一般表示地图可以用整型数组1、0  或字符数组中的字符

 

[迷宫之判定]

 

 重点思路

 

【算法分析】
dfs,不回溯,如果下一个点符合条件则继续递归,直到找到终点。

vis[][] //vis[x][y]标记点(x,y)是否已访问
DFS(int x, int y)  //当前正在访问的点是(x,y)
    if (x, y) 是终点 //边界
       走到终点
       return    //返回
    vis[x][y] = true  //标记点(x,y)已访问
    for 点(x, y)的上下左右点(nx,ny)
        if(nx,ny)没越界&&(nx,ny)未访问&&(nx,ny)不是墙
            DFS(nx,ny)  //递归访问点(nx,ny)

【参考代码】
#include <iostream>
using namespace std;

const int N = 50;
int n, m;
int mp[N][N];
int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};  
bool vis[N][N], flag;         //vis[x][y] 标记点(x,y)是否已访问

bool check(int x, int y){
    return x >= 1 && x <= n && y >= 1 && y <= m;
}

void dfs(int x, int y){      //当前正在访问的点是(x,y)
    if(x == n && y == m){  //边界
        flag = true;
        return;
    }
    vis[x][y] = true;      //标记点(x,y)已访问
    for(int i = 0; i < 4; i++){
        int nx = x + dir[i][0];
        int ny = y + dir[i][1];
        if(check(nx, ny) && !vis[nx][ny] && !mp[nx][ny]){
            dfs(nx,ny);    //递归访问点(nx,ny) 
        }
    }
}

int main() {
    cin >> n >> m;
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            cin >> mp[i][j];    
        }
    }
    dfs(1,1);
    if(flag) cout << "YES";
    else cout << "NO";
    return 0;
}
View Code

 

[迷宫之方案数](回溯知识)

回溯指的是状态重置,可以理解为回到过去,恢复现场是在编码的过程中,是为了节约空间而使用的一种技巧,而回溯算法其实是深度优先遍历特有的一种现象。之所以是深度优先遍历,是因为我们要解决的问题通常是在一颗树上完成的,在这颗树上搜索需要的答案,一般使用深度优先遍历

 

【算法分析】
每到一次终点,说明找到一种新方案。
到达终点后,不要停止,回头继续找其他路。
不会完全重复,因为走过的地方被标记了。

【参考代码】
#include <iostream>
using namespace std;

const int N = 15;
int n, m, sx, sy, fx, fy, t, cnt;
int mp[N][N];
int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};  
bool vis[N][N];         //vis[x][y] 标记点(x,y)是否已访问

bool check(int x, int y){
    return x >= 1 && x <= n && y >= 1 && y <= m;
}

void dfs(int x, int y){      // 当前位置 (x, y) 
    if(x == fx && y == fy){ // 边界:终点  
        cnt++;                // 方案数加 1
        return;
    }
    vis[x][y] = true;      // 标记已经走过 
    for(int i = 0; i < 4; i++){
        int nx = x + dir[i][0];
        int ny = y + dir[i][1];
        // 没有越界 && 没有访问 && 不是障碍物
        if(check(nx,ny) && !vis[nx][ny] && mp[nx][ny] != 1){
            dfs(nx, ny);
        }
    }
    vis[x][y] = false;  //回溯 
}

int main() {
    cin >> n >> m >> t;
    cin >> sx >> sy >> fx >> fy;
    for(int i = 1; i <= t; i++){
        int x, y;
        cin >> x >> y;
        mp[x][y] = 1;
    }
    dfs(sx,sy);
    cout << cnt;
    return 0;
}
View Code

 

 

初赛知识:

"应用软件是为满足特定用户需求而设计和开发的程序,用于完成各种任务和活动。" 应用软件是指在计算机上运行的具体应用程序,旨在满足用户的特定需求,并提供各种功能和服务,例如办公软件、游戏、媒体播放器等。应用软件是根据用户需求进行开发和设计的,以便满足用户在各种任务和活动中的要求。

 

 

[迷宫之最少花费时间]

 

 

【算法分析】
dfs,回溯,如果下一个点符合条件则继续递归,直到找到终点。

mp[][]  //迷宫
vis[][] //vis[x][y]标记点(x,y)是否已访问
DFS(int x, int y, int sum)  //当前正在访问的点是(x,y)
    if (x, y) 是终点 //边界
       走到终点 更新最短时间ans
       return    //返回
    vis[x][y] = true  //标记点(x,y)已访问
    for 点(x, y)的上下左右点(nx,ny)
        if(nx,ny)没越界&&(nx,ny)未访问&&(nx,ny)不是墙
            if 是怪兽
            DFS(nx,ny,sum + (mp[nx][ny] - '0') + 1)  //需要花费 1 分钟 + 消灭怪兽的时间 
            else 
            DFS(nx, ny, sum + 1);  // 空地需要花费 1 分钟
    回溯
【参考代码】
#include <iostream>
using namespace std;

const int N = 30;
char mp[N][N];  // 迷宫
int n, m, ans = 2e9;  // 行,列,最短时间 
int sx, sy, ex, ey;  // (sx, sy) 起点,(ex, ey) 终点 
int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};  // 方向数组
bool vis[N][N];  // 标记数组 

bool in(int x, int y) {
    return x >= 1 && x <= n && y >= 1 && y <= m;
}

// 搜索所有可能路径,并维护一个最短时间 
void DFS(int x, int y, int sum) {  // 正在访问 (x, y),所花时间为 sum 
    if(x == ex && y == ey) {  // 走到终点 
        if(sum < ans) ans = sum;  // 更新最短时间
        return;  // 到达递归边界,返回 
    }
    vis[x][y] = true;
    for(int i = 0; i < 4; i++) {
        int nx = x + dir[i][0];
        int ny = y + dir[i][1];
        // 未越界 && 未访问 && 不是障碍物和墙 
        if(in(nx, ny) && !vis[nx][ny] && mp[nx][ny] != '#') {
            if(mp[nx][ny] >= '1' && mp[nx][ny] <= '9')
                DFS(nx, ny, sum + (mp[nx][ny] - '0') + 1);  // 需要花费 1 分钟 + 消灭怪兽的时间 
            else
                DFS(nx, ny, sum + 1);  // 空地需要花费 1 分钟
        }
    }
    vis[x][y] = false;  // 回溯 
}

int main() {
    cin >> n >> m;
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= m; j++) {
            cin >> mp[i][j];
            if(mp[i][j] == 'Z') sx = i, sy = j;  // 起点位置
            if(mp[i][j] == 'W') ex = i, ey = j;  // 终点位置 
        }
    }
    DFS(sx, sy, 0);  // 从起点出发,找到到达终点的最短时间(也有可能找不到)
    if(ans == 2e9) cout << "IMPOSSIBLE";  // 从起点无法到达终点
    else cout << ans; 
    return 0;
}
View Code

 

 

本节课作业讲解视频:

稍等,正在整理中···

 

标签:02,ny,U5,vis,C++,nx,int,mp,&&
From: https://www.cnblogs.com/jayxuan/p/17982628

相关文章

  • 2023京东零售技术年度盘点
    过去一年,围绕开放生态建设、低价心智等主要方向,京东零售技术团队持续攻坚。从百亿补贴、调整流量分配机制为用户提供低价品质好货,到简化商家进驻流程、优化商家体验,带动商家数量增长和平台生态活跃,再到将大模型结合到内部大量业务场景,探索效率提升……快速响应、助力业务的同时,京......
  • 【专题】2023年大语言模型综合评测报告PDF合集分享(附原数据表)
    原文链接:https://tecdat.cn/?p=33624原文出处:拓端数据部落公众号自2022年年末以来,人工智能大模型已成为技术领域甚至全球创新领域最受关注的话题。以ChatGPT为代表的大模型产品发展迅速,预测数据显示,到2030年,AIGC市场规模有望超过万亿元。2023年,国内主要厂商也相继推出自研的大语......
  • LOJ3990/LG9602 IOI2023 足球场 题解 (区间DP+精简无用状态)
    首先考虑一个足球场长啥样才是合法的。发现一个点能只拐弯一次到达另一个点,可以分为两种情况:先左右走,再上下走或先上下走,后左右走。无论哪种情况,都要求我们走一步使得和目标点一个轴相同,再走一步使得另一个轴也相同,所以加入把每一行选择的格子看成一个区间(因为如果不连续显然是......
  • 【专题】2023年新能源汽车、智能汽车、车险行业报告汇总PDF合集分享(附原数据表)
    原文链接:https://tecdat.cn/?p=34910本文主要研究了汽车品牌的影响力以及汽车行业的营销新增量。通过调研新能源汽车及用户需求、特点和偏好,分析了中国新能源汽车市场的发展趋势和内容生态。同时,探讨了智能汽车的发展趋势、云服务和数字化人才需求。此外,还分析了中国汽车出海、新......
  • 【专题】中国中小企业数字化转型研究报告(2022)PDF合集分享(附原数据表)
    原文链接:https://tecdat.cn/?p=33471数字化转型指数报告2022合集根据“基础设施-平台-应用”三层指标体系,对全国300余个城市、10余个行业的数字化发展规模进行了评估。该报告提供了覆盖全国范围的季度数字化转型指数,为各行各业推进数字化转型提供了有益的参考。报告的评估结果可以......
  • 2024-1-23AJAX的概念
    目录AJAX的概念小知识点箭头函数AJAX的作用axios的使用AJAX的概念简单可以理解为想指定的url获取指定的数据。小知识点箭头函数箭头函数是一种新的函数语法,旨在提供一种更简洁的方式来编写函数。它与传统的function相比比较容易传统函数格式varsum=function(a,b){r......
  • UE C++一些记录
    #include<windows/WindowsWindow.h>#include"Windows/AllowWindowsPlatformTypes.h"#include<windows.h>#include<shellapi.h>#include"Windows/HideWindowsPlatformTypes.h"UUETuioBPLibrary::UUETuioBPLibrary(constFO......
  • 2023年春秋杯网络安全联赛冬季赛-CRYPTO MISC WP
    浅谈:*代表未做出的,赛后复现了一下。本次题目还是挺有意思的,比赛期间做啦俩。题目有很多值得学习的东西。顺便在此记录一下。继续努力吧!!CRYPTOnot_wiener(中等)题目附件查看代码fromCrypto.Util.numberimport*fromgmpy2import*importrandom,osfromhashlibimport......
  • 2024年世界经济论坛年会,人工智能议题引发热议
    2024年1月15日至19日,瑞士达沃斯举办了第54届世界经济论坛年会。此次论坛汇聚了来自120个国家的2800多位各界领导者,共同探讨和推动国际合作,围绕“重建信任”这一主题讨论经济增长、气候与自然行动、能源安全、技术治理和人类发展等重要议题。论坛设置了包括世界安全合作、创造就业机......
  • C++auto关键字
    auto用来干啥在C语言中,auto是用来修饰局部变量的,意味着该变量在该代码块内要有效,出代码块自动销毁但是在C++中,有了新的用法:自动推导变量类型inta=10;autob=a;//自动推导b的类型为a的类型(整形)autoc='c';//自动推导c的类型为字符型autosum=Add(a,b);//自动推导su......