当前位置: 首页 > news >正文

【C++BFS算法 二分查找】2812. 找出最安全路径

本文涉及知识点

C++BFS算法
C++二分查找

LeetCode2812. 找出最安全路径

给你一个下标从 0 开始、大小为 n x n 的二维矩阵 grid ,其中 (r, c) 表示:
如果 grid[r][c] = 1 ,则表示一个存在小偷的单元格
如果 grid[r][c] = 0 ,则表示一个空单元格
你最开始位于单元格 (0, 0) 。在一步移动中,你可以移动到矩阵中的任一相邻单元格,包括存在小偷的单元格。
矩阵中路径的 安全系数 定义为:从路径中任一单元格到矩阵中任一小偷所在单元格的 最小 曼哈顿距离。
返回所有通向单元格 (n - 1, n - 1) 的路径中的 最大安全系数 。
单元格 (r, c) 的某个 相邻 单元格,是指在矩阵中存在的 (r, c + 1)、(r, c - 1)、(r + 1, c) 和 (r - 1, c) 之一。
两个单元格 (a, b) 和 (x, y) 之间的 曼哈顿距离 等于 | a - x | + | b - y | ,其中 |val| 表示 val 的绝对值。
示例 1:
在这里插入图片描述

输入:grid = [[1,0,0],[0,0,0],[0,0,1]]
输出:0
解释:从 (0, 0) 到 (n - 1, n - 1) 的每条路径都经过存在小偷的单元格 (0, 0) 和 (n - 1, n - 1) 。
示例 2:
在这里插入图片描述

输入:grid = [[0,0,1],[0,0,0],[0,0,0]]
输出:2
解释:
上图所示路径的安全系数为 2:

  • 该路径上距离小偷所在单元格(0,2)最近的单元格是(0,0)。它们之间的曼哈顿距离为 | 0 - 0 | + | 0 - 2 | = 2 。
    可以证明,不存在安全系数更高的其他路径。
    示例 3:
    在这里插入图片描述

输入:grid = [[0,0,0,1],[0,0,0,0],[0,0,0,0],[1,0,0,0]]
输出:2
解释:
上图所示路径的安全系数为 2:

  • 该路径上距离小偷所在单元格(0,3)最近的单元格是(1,2)。它们之间的曼哈顿距离为 | 0 - 1 | + | 3 - 2 | = 2 。
  • 该路径上距离小偷所在单元格(3,0)最近的单元格是(3,2)。它们之间的曼哈顿距离为 | 3 - 3 | + | 0 - 2 | = 2 。
    可以证明,不存在安全系数更高的其他路径。

提示:
1 <= grid.length == n <= 400
grid[i].length == n
grid[i][j] 为 0 或 1
grid 至少存在一个小偷

二分查找

一,BFS出各单格距离小偷的位置(层次)leve。
二,二分查找。Check(mid) 是否存在安全系数为mid或更大的路径。随着mid从0到leve[0][0],Check的返回值逐步由true,变成false。我们寻找最后一个true。Check函数的大致步骤:
a,连通距离小偷大于等与mid的单格。
b,看右下角的层次是否大于等于0。

代码

第一版(超时)

class CGrid {
public:CGrid(int rCount, int cCount) :m_r(rCount), m_c(cCount) {}vector<vector<pair<int, int>>> NeiBo(std::function<bool(int, int)> funVilidCur, std::function<bool(int, int)> funVilidNext, int iConnect = 4){vector<vector<pair<int, int>>> vNeiBo(m_r * m_c);auto Move = [&](int preR, int preC, int r, int c){if ((r < 0) || (r >= m_r)){return;}if ((c < 0) || (c >= m_c)){return;}if (funVilidCur(preR, preC) && funVilidNext(r, c)){vNeiBo[Mask(preR, preC)].emplace_back(r, c);}};for (int r = 0; r < m_r; r++){for (int c = 0; c < m_c; c++){for (int k = 0; k < iConnect; k++){Move(r, c, r + s_Moves[k][0], c + s_Moves[k][1]);}}}return vNeiBo;}void EnumGrid(std::function<void(int, int)> call){for (int r = 0; r < m_r; r++){for (int c = 0; c < m_c; c++){call(r, c);}}}	vector<pair<int, int>> GetPos(std::function<bool(int, int)> fun) {vector<pair<int, int>> ret;for (int r = 0; r < m_r; r++){for (int c = 0; c < m_c; c++){if (fun(r, c)) {ret.emplace_back(r, c);}}}return ret;}inline int Mask(int r, int c) { return  m_c * r + c; }const int m_r, m_c;const inline static int s_Moves[][2] = { {1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1} };
};class CBFSLeve {
public :static vector<int> Leve(const vector<vector<int>>& neiBo, vector<int> start) {vector<int> leves(neiBo.size(), -1);for (const auto& s : start) {leves[s] = 0;}for (int i = 0; i < start.size(); i++) {for (const auto& next : neiBo[start[i]]) {if (-1 != leves[next]) { continue; }leves[next] = leves[start[i]]+1;start.emplace_back(next);}}return leves;}static vector<vector<int>> Leve(CGrid& grid, vector<pair<int, int>> start, std::function<bool(int, int)> funVilidCur, std::function<bool(int, int)> funVilidNext, int iConnect = 4 ) {auto neiBo = grid.NeiBo(funVilidCur, funVilidCur, iConnect);vector<vector<int>> leves(grid.m_r, vector<int>(grid.m_c, -1));for (const auto& [r,c] : start) {leves[r][c] = 0;}for (int i = 0; i < start.size(); i++) {const int iMask = grid.Mask(start[i].first, start[i].second);for (const auto& [r1,c1] : neiBo[iMask]) {if (-1 != leves[r1][c1]) { continue; }leves[r1][c1] = leves[start[i].first][start[i].second] + 1;start.emplace_back(r1,c1);}}return leves;}
};template<class INDEX_TYPE>
class CBinarySearch
{
public:CBinarySearch(INDEX_TYPE iMinIndex, INDEX_TYPE iMaxIndex):m_iMin(iMinIndex),m_iMax(iMaxIndex) {}template<class _Pr>INDEX_TYPE FindFrist( _Pr pr){auto left = m_iMin - 1;auto rightInclue = m_iMax;while (rightInclue - left > 1){const auto mid = left + (rightInclue - left) / 2;if (pr(mid)){rightInclue = mid;}else{left = mid;}}return rightInclue;}template<class _Pr>INDEX_TYPE FindEnd( _Pr pr){int leftInclude = m_iMin;int right = m_iMax + 1;while (right - leftInclude > 1){const auto mid = leftInclude + (right - leftInclude) / 2;if (pr(mid)){leftInclude = mid;}else{right = mid;}}return leftInclude;}
protected:const INDEX_TYPE m_iMin, m_iMax;
};class Solution {public:int maximumSafenessFactor(vector<vector<int>>& grid) {CGrid ng(grid.size(),grid[0].size());auto start = ng.GetPos([&](int r, int c) {return grid[r][c] == 1; });auto vilid = [&](int r, int c) {return true; };auto leve = CBFSLeve::Leve(ng, start,vilid, vilid);auto Check = [&](int mid) {auto vilid1 = [&](int r, int c) {return leve[r][c] >= mid; };auto leve1 = CBFSLeve::Leve(ng, { {0,0 } }, vilid1, vilid1);return leve1.back().back() >= 0;};CBinarySearch<int> bs(0, leve[0][0]);return bs.FindEnd(Check);}};

第二版

中间过程,求临接表浪费很多时间,省略后,速度提高几倍。就可以过了。许多单格和起点不连通,无需计算。

class CGrid {
public:CGrid(int rCount, int cCount) :m_r(rCount), m_c(cCount) {}template<class Fun1,class Fun2>vector<vector<pair<int, int>>> NeiBo(Fun1 funVilidCur, Fun2 funVilidNext, int iConnect = 4){vector<vector<pair<int, int>>> vNeiBo(m_r * m_c);for (int r = 0; r < m_r; r++){for (int c = 0; c < m_c; c++){if (!funVilidCur(r, c))continue;auto& v = vNeiBo[Mask(r, c)];if ((r > 0)&& funVilidNext(r-1, c)) {v.emplace_back(r-1, c);}if ((c > 0) && funVilidNext(r , c - 1)) {v.emplace_back(r, c - 1);}if ((r+1 < m_r ) && funVilidNext(r + 1, c)) {v.emplace_back(r + 1, c);}if ((c+1 <m_c ) && funVilidNext(r, c + 1)) {v.emplace_back(r, c + 1);}}}return vNeiBo;}void EnumGrid(std::function<void(int, int)> call){for (int r = 0; r < m_r; r++){for (int c = 0; c < m_c; c++){call(r, c);}}}	vector<pair<int, int>> GetPos(std::function<bool(int, int)> fun) {vector<pair<int, int>> ret;for (int r = 0; r < m_r; r++){for (int c = 0; c < m_c; c++){if (fun(r, c)) {ret.emplace_back(r, c);}}}return ret;}inline int Mask(int r, int c) { return  m_c * r + c; }const int m_r, m_c;const inline static int s_Moves[][2] = { {1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1} };
};class CBFSLeve {
public :static vector<int> Leve(const vector<vector<int>>& neiBo, vector<int> start) {vector<int> leves(neiBo.size(), -1);for (const auto& s : start) {leves[s] = 0;}for (int i = 0; i < start.size(); i++) {for (const auto& next : neiBo[start[i]]) {if (-1 != leves[next]) { continue; }leves[next] = leves[start[i]]+1;start.emplace_back(next);}}return leves;}static vector<vector<int>> Dis(CGrid& grid, vector<pair<int, int>> start, std::function<bool(int, int)> funVilidCur, std::function<bool(int, int)> funVilidNext, const int& iConnect = 4 ) {static short dir[8][2] = { {0, 1}, {1, 0}, {-1, 0},{ 0, -1},{1,1},{1,-1},{-1,1},{-1,-1} };vector<vector<int>> vDis(grid.m_r, vector<int>(grid.m_c, -1));for (const auto& [r,c] : start) {vDis[r][c] = 0;}for (int i = 0; i < start.size(); i++) {const auto [r,c] = start[i];if (!funVilidCur(r, c)) { continue; }for (int k = 0; k < iConnect; k++) {const int r1 = r + dir[k][0];const int c1 = c + dir[k][1];if ((r1 < 0) || (r1 >= grid.m_r) || (c1 < 0) || (c1 >= grid.m_c)) { continue; }if (funVilidNext(r1, c1)&&(-1 == vDis[r1][c1])) {start.emplace_back(r1, c1);vDis[r1][c1]= vDis[r][c] + 1;}}}return vDis;}
};template<class INDEX_TYPE>
class CBinarySearch
{
public:CBinarySearch(INDEX_TYPE iMinIndex, INDEX_TYPE iMaxIndex):m_iMin(iMinIndex),m_iMax(iMaxIndex) {}template<class _Pr>INDEX_TYPE FindFrist( _Pr pr){auto left = m_iMin - 1;auto rightInclue = m_iMax;while (rightInclue - left > 1){const auto mid = left + (rightInclue - left) / 2;if (pr(mid)){rightInclue = mid;}else{left = mid;}}return rightInclue;}template<class _Pr>INDEX_TYPE FindEnd( _Pr pr){int leftInclude = m_iMin;int right = m_iMax + 1;while (right - leftInclude > 1){const auto mid = leftInclude + (right - leftInclude) / 2;if (pr(mid)){leftInclude = mid;}else{right = mid;}}return leftInclude;}
protected:const INDEX_TYPE m_iMin, m_iMax;
};class Solution {public:int maximumSafenessFactor(vector<vector<int>>& grid) {CGrid ng(grid.size(),grid[0].size());		auto start = ng.GetPos([&](int r, int c) {return grid[r][c] == 1; });auto vilid = [&](int r, int c) {return true; };auto dis = CBFSLeve::Dis(ng, start,vilid, vilid);auto Check = [&](int mid) {auto vilid1 = [&](int r, int c) {return dis[r][c] >= mid; };auto dis2 = CBFSLeve::Dis(ng, { {0,0} }, vilid1, vilid1);return dis2.back().back() >= 0;};CBinarySearch<int> bs(0, min(dis[0][0],dis.back().back()));return bs.FindEnd(Check);}};

单元测试

vector<vector<int>> grid;TEST_METHOD(TestMethod1){grid = { {1} };auto res = Solution().maximumSafenessFactor(grid);AssertEx(0, res);}TEST_METHOD(TestMethod15){grid = { {1,0,0},{0,0,0},{0,0,1} };auto res = Solution().maximumSafenessFactor(grid);AssertEx(0, res);}TEST_METHOD(TestMethod16){grid = { {0,0,1},{0,0,0},{0,0,0} };auto res = Solution().maximumSafenessFactor(grid);AssertEx(2, res);}TEST_METHOD(TestMethod17){grid = { {0,0,0,1},{0,0,0,0},{0,0,0,0},{1,0,0,0} };auto res = Solution().maximumSafenessFactor(grid);AssertEx(2, res);}TEST_METHOD(TestMethod18){grid.assign(400, vector<int>(400));grid[0][0] = 1;auto res = Solution().maximumSafenessFactor(grid);AssertEx(0, res);}TEST_METHOD(TestMethod19){grid.assign(400, vector<int>(400));grid.back().back() = 1;auto res = Solution().maximumSafenessFactor(grid);AssertEx(0, res);}TEST_METHOD(TestMethod20){grid.assign(400, vector<int>(400));grid[0].back() = 1;auto res = Solution().maximumSafenessFactor(grid);AssertEx(399, res);}TEST_METHOD(TestMethod21){grid.assign(400, vector<int>(400));grid.back()[0] = 1;auto res = Solution().maximumSafenessFactor(grid);AssertEx(399, res);}

扩展阅读

我想对大家说的话
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛
失败+反思=成功 成功+反思=成功

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

相关文章:

【C++BFS算法 二分查找】2812. 找出最安全路径

本文涉及知识点 CBFS算法 C二分查找 LeetCode2812. 找出最安全路径 给你一个下标从 0 开始、大小为 n x n 的二维矩阵 grid &#xff0c;其中 (r, c) 表示&#xff1a; 如果 grid[r][c] 1 &#xff0c;则表示一个存在小偷的单元格 如果 grid[r][c] 0 &#xff0c;则表示一…...

轻触开关 KH-4.5X4.5X5.5H-STM

品  牌&#xff1a; kinghelm(金航标) 厂家型号&#xff1a; KH-4.5X4.5X5.5H-STM 封装&#xff1a; SMD 商品毛重&#xff1a; 0.317克(g) 包装方式&#xff1a; 编带...

3.redis客户端

1.命令行客户端 在安装redis的时候就已经安装好了&#xff0c;就是redis-cli redis-cli -h 127.0.0.1 -p 6379 -a 123456 -a 表示密码 -h 表示ip&#xff0c;不配置默认为本机 127.0.0.1 -p 表示端口&#xff0c;不配置默认为 6379 进入后可以输入ping&#xff0c;返回pong代表…...

Rust配置国内源,解决安装依赖慢问题

温馨提示&#xff1a;最新内容仅在原文更新。 国内源使用字节的RsProxy https://rsproxy.cn/ 解决rust-analyzer加载时间过长(请参考本文) 配置环境变量 Mac export RUSTUP_DIST_SERVER"https://rsproxy.cn" export RUSTUP_UPDATE_ROOT"https://rsproxy.cn/r…...

AI学习指南机器学习篇- Q学习的参数与调优

AI学习指南机器学习篇- Q学习的参数与调优 在强化学习领域中&#xff0c;Q学习是一种经典的算法&#xff0c;可以用来解决各种问题&#xff0c;包括游戏和机器人控制等。Q学习算法的性能很大程度上取决于一些重要的参数&#xff0c;例如学习率和折扣因子。本文将介绍这些参数的…...

《小迪安全》学习笔记02

域名默认存放目录和IP默认存放目录不一样。 IP地址是WWW文件里的&#xff0c;域名访问是WWW里的一个子目录里的&#xff08;比如是blog&#xff09;。 Nmap: Web源码拓展 拿到一个网站的源码&#xff0c;要分析这几个方面↑。 不同类型产生的漏洞类型也不一样 在网站中&…...

C语言:自定义类型进阶(结构体、联合体、枚举)

自定义类型&#xff08;结构体、联合体、枚举&#xff09; 一、结构体&#xff08;一&#xff09;结构体的内存对齐1、结构体内存对齐规则&#xff08;1&#xff09;引子&#xff08;2&#xff09;offsetof 宏函数&#xff08;3&#xff09;内存对齐原理&#xff08;4&#xff…...

SPSSAU | 最好最差权重BWM原理及案例实操分析

BWM&#xff08;best-worse-method&#xff0c;最好最差法&#xff09;是一种多准则决策方法&#xff0c;由Jafar Rezaei于2015年提出&#xff0c;其通常用于确定决策标准的权重。其原理是比如5个指标&#xff0c;如果以前AHP就需要5个指标两两的相对重要性数据。但是现在简化为…...

docker安装elasticsearch(es)最新版本

docker安装elasticsearch&#xff08;es&#xff09; docker官网 https://hub.docker.com/ https://www.cnblogs.com/balloon72/p/13177872.html 1、拉取最新项目elasticsearch docker pull elasticsearch:8.14.3lscpu 查看架构 2、构建环境 mkdir -p /data/elasticsear…...

02 RabbitMQ:下载安装

02 RabbitMQ&#xff1a;下载&安装 1. 下载&安装1.1. 官网1.2. Docker方式1.2.1. 下载镜像1.2.2. 启动1.2.3. 登录验证 1. 下载&安装 1.1. 官网 RabbitMQ: One broker to queue them all | RabbitMQ 1.2. Docker方式 1.2.1. 下载镜像 # docker pull 镜像名称[…...

mmcv库出现No module named ‘mmcv._ext

遇到 "No module named mmcv._ext" 这个错误通常意味着你的 Python 环境中缺少 mmcv 库的扩展模块 _ext。mmcv&#xff08;MMDetection 训练工具箱的核心库&#xff09;通常依赖于 _ext 模块来提供一些高性能的操作&#xff0c;这些操作是用 C/C 实现的&#xff0c;并…...

防止xss(跨站脚本攻击)

1、输出数据时进行转义&#xff1a;这是最基本的预防措施。确保在输出数据到HTML时对特殊字符进行适当的转义&#xff0c;以防止它们被解释为HTML或JavaScript代码。PHP中可以使用htmlspecialchars()、strip_tags()、htmlentities函数来实现这一点。 echo htmlspecialchars($d…...

django小型超市库存与销售管理系统-计算机毕业设计源码46608

摘 要 随着信息技术的快速发展&#xff0c;超市库存与销售管理面临着前所未有的挑战与机遇。为了提升超市的运营效率&#xff0c;优化库存管理&#xff0c;并增强销售数据的分析能力&#xff0c;我们基于Django框架设计并开发了一套小型超市库存与销售管理系统。该系统充分利用…...

项目实战_表白墙(简易版)

你能学到什么 一个比较简单的项目&#xff1a;表白墙&#xff08;简易版&#xff09;&#xff0c;浏览器&#xff1a;谷歌升级版将在下个博客发布 效果如下 正文 说明 我们是从0开始一步一步做这个项目的&#xff0c;里面的各种问题&#xff0c;我也会以第一人称视角来解…...

优化 Spring Boot 项目启动速度:高效管理大量 Bean 注入

个人名片 🎓作者简介:java领域优质创作者 🌐个人主页:码农阿豪 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[2435024119@qq.com] 📱个人微信:15279484656 🌐个人导航网站:www.forff.top 💡座右铭:总有人要赢。为什么不能是我呢? 专栏导…...

《LeetCode热题100》---<5.普通数组篇六道>

本篇博客讲解LeetCode热题100道普通数组篇中的六道题 第一道&#xff1a;最大子数组和&#xff08;中等&#xff09; 第二道&#xff1a;合并区间&#xff08;中等&#xff09; 第一道&#xff1a;最大子数组和&#xff08;中等&#xff09; 法一&#xff1a;贪心算法 class So…...

【Hot100】LeetCode—169. 多数元素

目录 题目1- 思路2- 实现⭐169. 多数元素——题解思路 3- ACM 实现 题目 原题连接&#xff1a;169. 多数元素 1- 思路 定义两个变量 一个是 count&#xff1a;维护当前元素的出现次数一个是 ret &#xff1a;维护当前元素 思路 遍历整个数组**①如果 count 0 **&#xff…...

专科、本科、研究生是按照什么分类的?

高等教育按照阶段主要分为以下几类 一、专业学位教育 特点&#xff1a;职业导向 专业学位教育是针对特定职业领域的专业培训&#xff0c;如医学、法律、工程等&#xff0c;旨在使学生具备从事相关职业所需的专业知识和实践技能。 实践性 专业学位教育注重实践教学和职业技…...

关于实时ODS层数仓搭建的三个问题

目录 问题一&#xff1a;数据同步的实时性无法满足 问题二&#xff1a;批量数据同步计算处理效率低 问题三&#xff1a;没有稳定的数据传输管道 FineDataLink的解决方案 实战案例-销售部门与财务部门数据同步 设置ODS层实时同步任务 设置DW层增量数据同步 设置 DM 层任务汇总 关…...

微信仿H5支付是什么

仿H5支付是指一种模拟原生H5支付流程的非官方支付方式。这种支付方式通常是由第三方支付服务提供商开发和维护的&#xff0c;目的是为了绕过官方支付渠道的限制&#xff0c;如费率、审核等问题。然而&#xff0c;由于仿H5支付并非官方授权和认可的支付方式&#xff0c;其安全性…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...