搜索专项---最短路模型

news2024/11/30 8:42:32


文章目录

  • 迷宫问题
  • 武士风度的牛
  • 抓住那头牛

一、迷宫问题OJ链接

        本题思路:只需要记录各个点是有哪个点走过来的,就能递推得出路径。记录前驱假设从 1,1 这个点向下走到了2, 1,则将2,1这个点的前驱记为1,1。这样,将整张地图 bfs 后,各个点的前驱就被记录了下来。输出路径:经过 bfs ,各个点的前驱已经被记录下来,我们只需要从终点开始,依次找当前节点的前驱,就能一直找到起点,从而得到一条路径。当然,这条路径是终点到起点的路径,倒序输出即为起点到终点的路径。如果 bfs 是从终点开始,则讲过上述步骤,得到的就是从起点到终点的路径,不用倒序输出。

#include <bits/stdc++.h>

#define x first
#define y second

typedef std::pair<int,int> PII;

constexpr int N=1010;

int n;
int g[N][N];
bool st[N][N];
PII pre[N][N];//储存当前位置的前驱位置
std::queue<PII> q;

int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};

void bfs(int ax,int ay)
{
    q.push({ax,ay});
    st[ax][ay]=true;
    
    while(!q.empty()){
        PII t=q.front();
        q.pop();
        
        for(int i=0;i<4;i++){
            int a=t.x+dx[i],b=t.y+dy[i];
            if(a<0||a>=n||b<0||b>=n) continue;
            if(g[a][b]) continue;
            if(!st[a][b]){
                q.push({a,b});
                pre[a][b]=t;
                st[a][b]=true;
            }
        }
    }
    
}

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);std::cout.tie(nullptr);
    
    std::cin>>n;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            std::cin>>g[i][j];
    
    bfs(n-1,n-1);//从终点位置进行遍历
    
    PII end(0,0);
    while (true)
    {
        std::cout<<end.x<<" "<<end.y<<std::endl;
        if (end.x == n - 1 && end.y == n - 1) break;
        end = pre[end.x][end.y];
    }
}

二、武士风度的牛OJ链接

   本题题解: 从牛的起点,进行 bfs 即可。根据题意,牛走的是日字, 八个点。因此,dx, dy 和之前的四个点是不同的。可以得出:dx = [-2, -1, 1, 2, 2, 1, -1, -2],dy = [1, 2, 2, 1, -1, -2, -2, -1]
具体的:找到牛的起点,从起点开始进行 bfs向八个方向进行探索,判断这八个点是否合法:不越界和牛能走。对于合法的点,记录从起点走过来的距离,也就是上个点的距离+1。将合法的点放入队列。如果在 bfs过程中遇到了终点(干草) ,则返回答案。

#include <bits/stdc++.h>

#define x first
#define y second

typedef std::pair<int,int> PII;

constexpr int N=2000;

int n,m;
char g[N][N];
int dist[N][N];
std::queue<PII> q;

int dx[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
int dy[8] = {1, 2, 2, 1, -1, -2, -2, -1};

int bfs(int ax,int ay)
{
    memset(dist,-1,sizeof dist);
    dist[ax][ay]=0;
    q.push({ax,ay});
    
    while(!q.empty()){
        PII t=q.front();
        q.pop();
        
        for(int i=0;i<8;i++){
            int a=t.x+dx[i],b=t.y+dy[i];
            if(a<0||a>=n||b<0||b>=m) continue;
            if(g[a][b]=='*') continue;
            if(dist[a][b]!=-1) continue;
            if(g[a][b]=='H') return dist[t.x][t.y]+1;
            dist[a][b]=dist[t.x][t.y]+1;
            q.push({a,b});
        }
    }
    
}

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);std::cout.tie(nullptr);
    
    std::cin>>m>>n;
    for(int i=0;i<n;i++) std::cin>>g[i];
    
    int ax,ay;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            if(g[i][j]=='K'){
                ax=i;
                ay=j;
            }
    
    std::cout<<bfs(ax,ay)<<std::endl;
    return 0;
}

三、抓住那头牛OJ链接

       本题思路: 这道题是一个一维的找最短路径的问题,无论+1,-1,* 2 花费都是1分钟,即权值相同, 所以才能用BFS去找最短路。假设当前点为t , 目标点为k出队扩展循环判断 1、如果t-1小于0了,那就不能走-1的方法 2、如果t+1 大于了N(10的5次方+10 ),就不能走+1的方法。 3、如果t * 2大于了N,也就不能走* 2的方法了。当然三个判断都应该加上此点是否被走过的条件,如果满足条件,就把其入队,出队时判断t是否等于k,如果相等就return距离。那么为什么N要取的比K大一点呢,因为先减1再乘2扩大会比先乘再减一缩小更快的接近K,1、当k为偶数,假设为100,当前点为51,那么减一再乘更快,2、当k为奇数,假设为99,当前点为50,那么先乘再减一时更快一点的。所以N要取的比K大一点,当超过N的时候就不会有这样的区别,一定是先减再乘可以更快的接近K。

#include <bits/stdc++.h>

constexpr int N=1e5+10;

int n,k;
int dist[N];
std::queue<int> q;

int bfs()
{
    q.push(n);
    dist[n]=0;
    
    while(!q.empty()){
        auto t=q.front();
        q.pop();
        
        if(t==k) return dist[k];
        
        if(t-1>=0&&dist[t-1]==-1){
            q.push(t-1);
            dist[t-1]=dist[t]+1;
        }
        
        if(t+1<=N&&dist[t+1]==-1){
            q.push(t+1);
            dist[t+1]=dist[t]+1;
        }
        
        if(t*2<=N&&dist[t*2]==-1){
            q.push(t*2);
            dist[t*2]=dist[t]+1;
        }
    }
}

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);std::cout.tie(nullptr);
    
    memset(dist,-1,sizeof dist);
    std::cin>>n>>k;
    
    std::cout<<bfs()<<std::endl;
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1447629.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue 向某个网址 传递数据

1. 需求 现在有一个网站需要 配置上另一个网站的东西 类似这样的东西吧 就是我需要再一个网站上 右边或者其他地方 放另一个页面的地址 这个地址需要给我传递东西 或我这个网站给其他的网站传递token了 id等 2.解决 window.parent.postMessage({ token: loginRes.token, id:…

阿里云服务器公网带宽收费价格表_2024更新报价

阿里云服务器公网带宽怎么收费&#xff1f;北京地域服务器按固定带宽计费一个月23元/M&#xff0c;按使用流量计费0.8元/GB&#xff0c;云服务器地域不同实际带宽价格也不同&#xff0c;阿里云服务器网aliyunfuwuqi.com分享不同带宽计费模式下带宽收费价格表&#xff1a; 公网…

软件测试如何自我提升

当一个软件测试工程师刚刚进入行业一到三年的时间&#xff0c;他们通常需要掌握一些基本技能和知识&#xff0c;并且需要学习一些新的技术和工具&#xff0c;以便更好地完成自己的测试工作。以下是一些建议&#xff0c;帮助测试工程师在这个阶段提升自己的技能。 掌握基本的测…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 2月14日,星期三

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年2月14日 星期三 农历正月初五 1、 第十四届全国冬季运动会将于17日开幕&#xff0c;部分赛事今天起陆续开赛。 2、 2024年购房政策将进一步宽松&#xff0c;专家称今年买房性价比更高。 3、 春节档票房突破45亿元&#…

LeetCode、901. 股票价格跨度【中等,单调栈】

文章目录 前言LeetCode、901. 股票价格跨度【中等&#xff0c;单调栈】题目链接及分类思路思路1&#xff1a;暴力思路2&#xff1a;单调栈写法优化&#xff1a;单调栈简化写法(数组替代栈集合) 资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝2W&#xff0c;csdn博客专家、…

【王道数据结构】【chapter5树与二叉树】【P158t3】

编写后序遍历二叉树的非递归算法 #include <iostream> #include <stack> typedef struct treenode{char data;struct treenode *left;struct treenode *right; }treenode,*ptreenode;ptreenode buytreenode(char x) {ptreenode n(ptreenode) malloc(sizeof (treeno…

Amber-Leedcode-Java - 代码随想录打卡第38 - 39天-动态规划汇总

509. 斐波那契数 较为简单 746. 使用最小花费爬楼梯 62. 不同路径 一开始写的时候被吓到了&#xff0c;但是发现听完一半之后再写还是比较容易的 对于我而言主要是找到逻辑&#xff0c; class Solution {public int uniquePaths(int m, int n) {if (m < 1 || n <1){r…

蓝桥杯嵌入式第10届真题(完成) STM32G431

蓝桥杯嵌入式第10届真题(完成) STM32G431 题目 main.c /* USER CODE BEGIN Header */ /********************************************************************************* file : main.c* brief : Main program body********************************…

linux信号机制[一]

目录 信号量 时序问题 原子性 什么是信号 信号如何产生 引入 信号的处理方法 常见信号 如何理解组合键变成信号呢&#xff1f; 如何理解信号被进程保存以及信号发送的本质&#xff1f; 为什么要有信号 信号怎么用&#xff1f; 样例代码 core文件有什么用呢&#…

python系统学习Day1

section1 python introduction 文中tips只做拓展&#xff0c;可跳过。 PartOne introduction 首先要对于python这门语言有一个宏观的认识&#xff0c;包括特点和应用场景。 特点分析&#xff1a; 优势 提供了完善的基础代码库&#xff0c;许多功能不必从零编写简单优雅 劣势 运…

Linux环境下配置HTTP代理服务器教程

大家好&#xff0c;我是你们可爱的Linux小助手&#xff01;今天&#xff0c;我将带你们一起探索如何在Linux环境下配置一个HTTP代理服务器。请注意&#xff0c;这不是一次火箭科学的实验&#xff0c;而是一次简单而有趣的冒险。 首先&#xff0c;我们需要明确什么是HTTP代理服…

使用MICE进行缺失值的填充处理

在我们进行机器学习时&#xff0c;处理缺失数据是非常重要的&#xff0c;因为缺失数据可能会导致分析结果不准确&#xff0c;严重时甚至可能产生偏差。处理缺失数据是保证数据分析准确性和可靠性的重要步骤&#xff0c;有助于确保分析结果的可信度和可解释性。 在本文中&#…

【Linux学习】线程互斥与同步

目录 二十.线程互斥 20.1 什么是线程互斥&#xff1f; 20.2 为什么需要线程互斥? 20.3 互斥锁mutex 20.4 互斥量的接口 20.4.1 互斥量初始 20.4.2 互斥量销毁 20.4.3 互斥量加锁 20.4.4 互斥量解锁 20.4.5 互斥量的基本原理 20.4.6 带上互斥锁后的抢票程序 20.5 死锁问题 死锁…

怎么使用ChatGPT提高工作效率?

怎么使用ChatGPT提高工作效率&#xff0c;这是一个有趣的话题。 相信不同的人有不同的观点&#xff0c;大家的知识背景和从事的工作都不完全相同&#xff0c;所以最终ChatGPT能起到的作用也不一样。 在编程过程中&#xff0c;如果我们要找一个库&#xff0c;我们最先做的肯定…

python3 获取某个文件夹所有的pdf文件表格提取表格并一起合并到excel文件

下面是一个完整的示例&#xff0c;其中包括了merge_tables_to_excel函数的定义&#xff0c;并且假设该函数的功能是从每个PDF文件中提取第一个表格并将其合并到一个Excel文件中&#xff1a; import os from pathlib import Path import pandas as pd import pdfplumber …

GEE重投影——NICFI数据集重投影到WGS84坐标

简介 重投影 遥感影像的重投影是将一幅影像从一个地理坐标系统转换到另一个地理坐标系统的过程。在遥感应用中,重投影非常重要,因为不同的遥感影像可能来自于不同的遥感传感器或不同的地理坐标系统,而在进行数据分析和集成时,需要保证所有影像在同一地理坐标系统下。 重…

部分意图分类【LLM+RAG】

在生成人工智能领域工作最有价值的事情之一就是发现新兴技术如何融入新的解决方案。 举个例子&#xff1a;在为北美顶级金融服务公司之一设计对话式人工智能助手时&#xff0c;WillowTree 的数据和人工智能研究团队 (DART) 发现&#xff0c;将意图分类与大型语言模型 (LLM) 结合…

钓鱼邮件的发送工具GUI

一.简介 本程序利用Python语言编写&#xff0c;使用Tkinter实现图形化界面&#xff0c;可使用Pyinstaller进行exe打包&#xff0c;程序主界面截图如下&#xff1a; 二.功能 1.支持腾讯企业邮、网易企业邮、阿里企业邮、自建邮服SMTP授权账号&#xff08;其他邮服&#xff0c…

如果把vue组件动态添加到body上?

tools.js: import Vue from vue/*** param Component 组件实例的选项对象* param props 组件实例中的prop*/ export function create(Component, props) {const comp new (Vue.extend(Component))({ propsData: props }).$mount()document.body.appendChild(comp.$el)comp.re…

知识图谱与语言预训练:深度融合的智能问答时代

目录 前言1 直接使用预训练模型 vs. 知识图谱与预训练相结合1.1 直接使用预训练模型1.2 构建知识图谱后与预训练相结合 2 预训练语言模型的发展历程2.1 Word2Vec和GloVe2.2 ELMo2.3 BERT 3 知识图谱对预训练的助力3.1 弥补低频实体信息的不足3.2 提供领域知识的支持 4 典型知识…