码随想录算法训练营第62天|卡码网:97. 小明逛公园、127. 骑士的攻击

news2024/11/29 23:37:56

1. 卡码网 97. 小明逛公园

题目链接:https://kamacoder.com/problempage.php?pid=1155
文章链接:https://www.programmercarl.com/kamacoder/0097.小明逛公园.html

在这里插入图片描述

思路:
使用Floyd 算法,目的是解决多源最短路问题,即 求多个起点到多个终点的多条最短路径。
动规五部曲:
1、确定dp数组(dp table)以及下标的含义
用 grid数组来存图,那就把dp数组命名为 grid。
grid[i][j][k] = m,表示 节点i 到 节点j 以[1…k] 集合为中间节点的最短距离为m。
注意:[1…k] ,表示节点1 到 节点k 一共k个节点的集合。
2、确定递推公式
分两种情况:
1.节点i 到 节点j 的最短路径经过节点k
对于该情况,grid[i][j][k] = grid[i][k][k - 1] + grid[k][j][k - 1]
节点i 到 节点k 的最短距离 是不经过节点k,中间节点集合为[1…k-1],所以 表示为grid[i][k][k - 1]
节点k 到 节点j 的最短距离 也是不经过节点k,中间节点集合为[1…k-1],所以表示为 grid[k][j][k - 1]
2.节点i 到 节点j 的最短路径不经过节点k
对于该情况,grid[i][j][k] = grid[i][j][k - 1]
如果节点i 到 节点j的最短距离 不经过节点k,那么 中间节点集合[1…k-1],表示为 grid[i][j][k - 1]
因为我们是求最短路,对于这两种情况自然是取最小值。
即: grid[i][j][k] = min(grid[i][k][k - 1] + grid[k][j][k - 1], grid[i][j][k - 1])
3.dp数组如何初始化

vector<vector<vector<int>>> grid(n + 1, vector<vector<int>>(n + 1, vector<int>(n + 1, 10005)));  // C++定义了一个三位数组,10005是因为边的最大距离是10^4

for(int i = 0; i < m; i++){
    cin >> p1 >> p2 >> val;
    grid[p1][p2][0] = val;
    grid[p2][p1][0] = val; // 注意这里是双向图
} 

注意:输入数据没有涉及到的节点的情况都应该初始为一个最大数,此处设值为10005。
4.确定遍历顺序
初始化时,我们是把 k =0 的 i 和j 对应的数值都初始化了,这样才能去计算 k = 1 的时候 i 和 j 对应的数值。
因此,遍历k 的for循环一定是在最外面,遍历 i 和 j 的话,for 循环的先后顺序无所谓。

for (int k = 1; k <= n; k++) {
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            grid[i][j][k] = min(grid[i][j][k-1], grid[i][k][k-1] + grid[k][j][k-1]);
        }
    }
}
import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(); // 景点的数量
        int m = sc.nextInt(); // 道路的数量
        
        // 1. 定义dp数组和下标
        // dp[i][j][k] 表示节点i 到 节点j 以[1...k] 集合为中间节点的最短距离。
        int[][][] dp = new int[n+1][n+1][n+1];
        // 2. 递推公式
        // dp[i][j][k] = Math.min(dp[i][j][k-1],dp[i][k][k-1]+dp[k][j][k-1]);
        // 3. 初始化
        for (int i=0;i<=n;i++) {
            for (int j=0;j<=n;j++) {
                Arrays.fill(dp[i][j],10005);
            }
        }
        
        for (int i=0;i<m;i++) {
            int u = sc.nextInt();
            int v = sc.nextInt();
            int w = sc.nextInt();
            dp[u][v][0] = w;
            dp[v][u][0] = w;
        }
        
        //4. 遍历顺序
        for (int k=1;k<=n;k++) {
            for (int i=1;i<=n;i++) {
                for (int j=1;j<=n;j++) {
                    dp[i][j][k] = Math.min(dp[i][j][k-1],dp[i][k][k-1]+dp[k][j][k-1]);
                }
            }
        }
        
        int q = sc.nextInt();
        for (int i=0;i<q;i++) {
            int start = sc.nextInt();
            int end = sc.nextInt();
            if (dp[start][end][n] == 10005) {
                System.out.println(-1);
            } else {
                System.out.println(dp[start][end][n]);
            }
        }
    }
}

2. 卡码网 127. 骑士的攻击

题目链接:https://kamacoder.com/problempage.php?pid=1203
文章链接:https://www.programmercarl.com/kamacoder/0126.骑士的攻击astar.html

在这里插入图片描述
思路:
使用Astar算法, 关键在于 启发式函数, 也就是 影响 广搜或者 dijkstra 从 容器(队列)里取元素的优先顺序。

启发式函数 要影响的就是队列里元素的排序!
对队列里节点进行排序,就需要给每一个节点权值,如何计算权值呢?
每个节点的权值为F,给出公式为:F = G + H
1.G:起点达到目前遍历节点的距离
2.H:目前遍历的节点到达终点的距离
当前遍历节点的权值F:起点达到目前遍历节点的距离 + 目前遍历的节点到达终点的距离,就是起点到达终点的距离。
本题,采用欧拉距离才能最大程度体现 点与点之间的距离。
计算出来 F 之后,按照 F 的 大小,来选出队列中F最小的节点。

import java.util.*;

public class Main {
    static int[][] moves = new int[1001][1001];
    static int[][] dir = {{-2, -1}, {-2, 1}, {-1, 2}, {1, 2}, {2, 1}, {2, -1}, {1, -2}, {-1, -2}};
    static int b1, b2;

    static class Knight {
        int x, y;
        int g, h, f;

        public Knight(int x, int y, int g, int h, int f) {
            this.x = x;
            this.y = y;
            this.g = g;
            this.h = h;
            this.f = f;
        }
    }

    static class KnightComparator implements Comparator<Knight> {
        public int compare(Knight k1, Knight k2) {
            return k1.f - k2.f; // Java的优先队列默认是最小堆,所以这里用k1.f - k2.f来使得f值小的排在前面
        }
    }

    static PriorityQueue<Knight> que = new PriorityQueue<>(new KnightComparator());

    static int Heuristic(Knight k) { // 欧拉距离
        return (k.x - b1) * (k.x - b1) + (k.y - b2) * (k.y - b2);
    }

    static void astar(Knight k) {
        Knight cur, next;
        que.add(k);
        while (!que.isEmpty()) {
            cur = que.poll(); // 选出队列中F最小的节点
            if (cur.x == b1 && cur.y == b2) {
                break;
            }
            for (int i = 0; i < 8; i++) {
                next = new Knight(cur.x + dir[i][0], cur.y + dir[i][1], cur.g, 0, 0);
                if (next.x < 1 || next.x > 1000 || next.y < 1 || next.y > 1000) {
                    continue;
                }
                if (moves[next.x][next.y] == 0) {
                    moves[next.x][next.y] = moves[cur.x][cur.y] + 1;
                    next.g = cur.g + 5;
                    next.h = Heuristic(next);
                    next.f = next.g + next.h;
                    que.add(next);
                }
            }
        }
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        while (n-- > 0) {
            int a1 = scanner.nextInt();
            int a2 = scanner.nextInt();
            b1 = scanner.nextInt();
            b2 = scanner.nextInt();
            for (int[] row : moves) {
                Arrays.fill(row, 0);
            }
            Knight start = new Knight(a1, a2, 0, Heuristic(new Knight(a1, a2, 0, 0, 0)), 0);
            start.f = start.g + start.h;
            astar(start);
            System.out.println(moves[b1][b2]);
            que.clear(); // 清空队列
        }
        scanner.close();
    }
}

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

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

相关文章

【11】纯血鸿蒙HarmonyOS NEXT星河版开发0基础学习笔记-模块化语法与自定义组件

序言&#xff1a; 本文详细讲解了关于鸿蒙系统学习中的模块化语法与自定义组件&#xff0c;在模块化语法中我们学习到了多种导入导出方式&#xff0c;实现了在一个项目中&#xff0c;通过引用不同的组件&#xff0c;让我们整体代码的可读性更强&#xff0c;相当于我们把一个手…

【系统方案】系统设计方案书,可视化设计方案(word)

第 一 章 系统总体设计 1.1 总体架构 1.1.1 系统拓扑 1.1.2 系统组成 1.2 设计概述 1.3 平台系统功能 1.3.1 总部数据看板 1.3.2 项目部数据看板 1.3.3 视频联网系统 1.3.4 实名制考勤系统 1.3.5 安全生产系统 1.3.6 塔吊安全监控子系统 1.3.7 施工升降机安全监控管系统 1.3.8 …

聊天记录怎么监控?企业微信聊天记录监控的2个方法分享!员工权益vs企业管理

在企业管理与员工权益的平衡中&#xff0c;聊天记录的监控成为了一个备受争议的话题。 一方面&#xff0c;企业希望通过监控聊天记录来确保信息安全、规范员工行为&#xff0c;并防止潜在的风险&#xff1b; 另一方面&#xff0c;员工则强调个人隐私和沟通自由的重要性。 本文…

大模型技术进阶路线,有了基础应该怎么进阶?

“ 高性能大模型的打造&#xff0c;是一项复杂的系统性工程 ” 在上一篇文章中讲了学习大模型的基础路线&#xff0c;而如果是对有一定基础的人来说&#xff0c;应该怎么进阶呢&#xff1f;也就是说大模型更加高级的技术栈有哪些&#xff1f; 一个好的基础能够让你在学习的道…

《向量数据库指南》——Mlivus Cloud打造生产级AI应用利器

哈哈,各位向量数据库和AI应用领域的朋友们,大家好!我是大禹智库的向量数据库高级研究员王帅旭,也是《向量数据库指南》的作者。今天,我要和大家聊聊如何使用Mlivus Cloud来搭建生产级AI应用。这可是个热门话题哦,相信大家都非常感兴趣! 《向量数据库指南》 使用Mlivus …

降低大模型幻觉的5种方案

降低大模型幻觉的5种方案 大语言模型&#xff08;如GPT-4&#xff09;在生成文本时&#xff0c;有时会产生所谓的“幻觉”——即生成的内容虽然语法和逻辑上看似正确&#xff0c;但实际上是不准确或虚构的。为了减少这种现象&#xff0c;以下是五种有效的方案&#xff1a;Prom…

必备指南:人人适用的AI大模型学习路径!

23年 AI 大模型技术狂飙一年后&#xff0c;24年 AI 大模型的应用已经在爆发&#xff0c;因此掌握好 AI 大模型的应用开发技术就变成如此重要&#xff0c;那么如何才能更好地掌握呢&#xff1f;一份 AI 大模型详细的学习路线就变得非常重要&#xff01; 由于 AI 大模型应用技术…

R语言绘制散点图

散点图是一种在直角坐标系中用数据点直观呈现两个变量之间关系、可检测异常值并探索数据分布的可视化图表。它是一种常用的数据可视化工具&#xff0c;我们通过不同的参数调整和包的使用&#xff0c;可以创建出满足各种需求的散点图。 常用绘制散点图的函数有plot()函数和ggpl…

图解IP分类及子网掩码计算实例

一、什么是IP地址 在网络世界中&#xff0c;人们为了通信方便给每一台计算机都事先分配一个类似电话号码一样的标识地址&#xff0c;即IP地址。根据TCP/IP协议&#xff0c;IP地址由32位二进制数组成&#xff0c;而且在INTERNET范围内是唯一的。假如某台计算机IP地址为11000000…

基于SpringBoot vue 医院病房信息管理系统设计与实现

博主介绍&#xff1a;专注于Java&#xff08;springboot ssm 等开发框架&#xff09; vue .net php python(flask Django) 小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不然下次找…

SpringBoot+ElasticSearch7.12.1+Kibana7.12.1简单使用

案例简介 本案例是把日志数据保存到Elasticsearch的索引中&#xff0c;并通过Kibana图形化界面的开发工具给查询出来添加的日志数据&#xff0c;完成从0到1的简单使用 ElasticSearch职责用法简介 ElasticSearch用在哪 ElasticSearch在我这个案例中&#xff0c;不是用来缓解增…

牛市以一个什么视角看它?

这波指数行情连续上涨&#xff0c;我说过我没有任何情绪波动&#xff0c;我不想称之为牛市&#xff0c;而是一个增量周期&#xff0c;这样的话我的语言里尽量去除一些欲望和情绪的表达&#xff0c;有利于去给大家讲一些股市的客观存在规律&#xff1b;我们知道熊市的本质是什么…

重庆数字孪生工业互联网可视化技术,赋能新型工业化智能制造工厂

重庆作为西南地区的重要工业基地&#xff0c;正积极探索和实践数字孪生、工业互联网及可视化技术在智能制造领域的深度融合&#xff0c;致力于打造新型工业化智能制造工厂&#xff0c;为制造业的高质量发展注入强劲动力。 在重庆的智能制造工厂中&#xff0c;数字孪生技术被广…

为什么要学习大模型?AI在把传统软件当早餐吃掉?

前言 上周末在推特平台上有一篇写在谷歌文档里的短文&#xff0c;在国外的科技/投资圈得到了非常广泛的浏览&#xff0c;叫做 The End of Software&#xff08;软件的终结&#xff09;&#xff0c; 作者 Chris Paik 是位于纽约市的风险投资基金 Pace Capital 的创始合伙人&…

【预备理论知识——2】深度学习:线性代数概述

简单地说&#xff0c;机器学习就是做出预测。 线性代数 线性代数是数学的一个分支&#xff0c;主要研究向量空间、线性方程组、矩阵理论、线性变换、特征值和特征向量、内积空间等概念。它是现代数学的基础之一&#xff0c;并且在物理学、工程学、计算机科学、经济学等领域有着…

字符串和字符数组(2)

6.求字符串长度 C语言中有一个库函数叫strlen&#xff0c;这个函数是专门用来求字符串长度的。strlen的使用需要包含一个头文件string.h。 strlen函数统计的是字符串中\0之前的字符个数&#xff0c;所以传递给strlen函数的字符串中必须得包含\0. 请看代码&#xff1a; #inc…

AFSim仿真系统 --- 系统简解_04 Mystic(“情报处理模块”或“智能决策支持系统”)

Mystic应用 Mystic应用&#xff08;Mystic&#xff09;是一个主要的WSF应用程序&#xff0c;用于可视化模拟结果和统计数据。 当在场景中提供event_pipe命令块时&#xff0c;模拟结果将被记录。event_pipe块会创建AFSIM事件录制文件&#xff08;.aer&#xff09;&#xff0c;…

家政服务|基于springBoot的家政服务平台设计与实现(附项目源码+论文+数据库)

私信或留言即免费送开题报告和任务书&#xff08;可指定任意题目&#xff09; 目录 一、摘要 二、相关技术 三、系统设计 四、数据库设计 五、核心代码 六、论文参考 七、源码获取 一、摘要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数…

璞华科技×珠海采筑:通过SRM系统实现采购管理一体化和精细化

SRM供应商关系管理应该怎么做&#xff1f;如何实现采购管理一体化&#xff1f;近日&#xff0c;聚焦建材采购交易领域的服务商珠海采筑和SRM系统提供商璞华科技通过合作给出了一个现实的回答&#xff1a;通过SRM系统&#xff0c;聚焦使用者视角&#xff0c;以数据为主线&#x…

二分算法详解

1. 二分查找 704. 二分查找 这是一道单纯的朴素二分模版题&#xff0c;当 left right 时的这种情况也是需要考虑的&#xff0c;因为不排除数组中只有一个数的情况&#xff0c;或者是二分到数组中只剩一个数的情况&#xff0c;所以循环条件要写 left < right class Soluti…