【C++BFS算法】2998. 使 X 和 Y 相等的最少操作次数

news2024/9/23 21:20:34

本文涉及知识点

C++BFS算法

LeetCode2998. 使 X 和 Y 相等的最少操作次数

给你两个正整数 x 和 y 。
一次操作中,你可以执行以下四种操作之一:
如果 x 是 11 的倍数,将 x 除以 11 。
如果 x 是 5 的倍数,将 x 除以 5 。
将 x 减 1 。
将 x 加 1 。
请你返回让 x 和 y 相等的 最少 操作次数。

示例 1:
输入:x = 26, y = 1
输出:3
解释:我们可以通过以下操作将 26 变为 1 :

  1. 将 x 减 1
  2. 将 x 除以 5
  3. 将 x 除以 5
    将 26 变为 1 最少需要 3 次操作。
    示例 2:

输入:x = 54, y = 2
输出:4
解释:我们可以通过以下操作将 54 变为 2 :

  1. 将 x 加 1
  2. 将 x 除以 11
  3. 将 x 除以 5
  4. 将 x 加 1
    将 54 变为 2 最少需要 4 次操作。
    示例 3:

输入:x = 25, y = 30
输出:5
解释:我们可以通过以下操作将 25 变为 30 :

  1. 将 x 加 1
  2. 将 x 加 1
  3. 将 x 加 1
  4. 将 x 加 1
  5. 将 x 加 1
    将 25 变为 30 最少需要 5 次操作。

提示:
1 <= x, y <= 104

堆优化迪斯氏单源最短路

令最优解为path = {n0,n1,n2,n3, … \dots nn}。x=n1,y=nn。
性质一:path中不会存在重复的元素。令path[i]等于path[j],则删除path[i…j-1]是更优解。
性质二:i < j path[i] < path[j],则path[i+1…j-1]一定包括path[i+1]到path[j-1]之间所有数。下面用反证法来证明:
令x ∈ \in [path[i]+1,path[j]-1],path[i+1…j-1]之间不存在x。令path[k]是第一个大于x,故path[k-1] < x。path[k-1]无论如何操作,都<=x,与假设矛盾。
推论一:根据性质二,i < j path[i] < path[j] j-i >= path[j]-path[i]。 存在最优解:path[i] path[i]+1 path[i]+2 ⋯ \cdots path[j]。故x1 < x2,x1变x2 最少需要x2-x1次。

path[i]都在[0,10000]中,那状态数只有10000种。我们来分析存是否存在path[i]<1或path[i] >10000。
一,不会存在path[i2]<0。
令path[i2]不在[0,10000],前面在[0,10000]的数i1,后面在[0,10000]的数i3。path[i1]和path[i2]一定都是0,和性质一矛盾。
二,存在path[i2] > 10000。
path[i2…i3-1]一定不是除法的结果。反证法:令path[i4]除法的结果,则path[i4-1] > 50000。根据性质二:path[i2…i4-1]一定包括path[i4],与性质一矛盾。path[i3]可能是除法的结果。
不会有减法:令path[i4]是减法,则path[i1] <= 10000 < path[i4] < path[i4-1]=path[i4]+1,根据性质二:path[i1…i4-1]之间一定有path[i4],与性质一矛盾。故只有一种可能:
path[i1…i3-1]全部是++,path[i3-1]除以5或11。即path[i1]一定是10000。
如果n1 ∈ \in [0,9999]则顶多4条出边。
n1=10000顶多20000左右出边。
n1 → \rightarrow 11x → \rightarrow x
n1 → \rightarrow 5x → \rightarrow x
由于权重不为1,所以不能使用BFS。由于是稀疏图,故用堆优化迪斯氏单源最短路。

BFS

根据推论一,y >=x,需要y-x次。下面只讨论y < x。
一,假定path没有除法,即只有加减法。则一定是n1个++,n2个–。n2-n1=x-y。显然最优解是:x-y个减法。
二,如果有除法,则除法之前可能有加法。不失一般性,只讨论除以5,不讨论除以11。
如果x是5的倍数,则直接除,不需要加。
如果x不是5倍数,则加到x1就不加了。x1是5倍数,x1 > x ,x1尽可能的小。
这两个本质是一个问题,下面来证明:
令x=5 × \times ×x1
x → x + 5 → x 1 + 1 x\rightarrow x+5 \rightarrow x1+1 xx+5x1+1 操作6次
x → x 1 → x 1 x\rightarrow x1 \rightarrow x1 xx1x1操作2次
故:path[i] ∈ \in [0,10011],状态只需要考虑[0,10011]
BSF的状态:leves[i] 记录x经过i次操作能形成的数。
BFS的后续状态:cur经过4种操作得到的数next,next ∈ \in [0,10011]。
BFS的初始状态:leves[0] = {x}
BFS的返回值:如果cur等于y,返回i。
BFS的重复处理:数组leves出重。

核心代码

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;
	}

	
};

class Solution {
		public:
			int minimumOperationsToMakeEqual(int x, int y) {
				if (y >= x) { return y - x; }
				const int iMax = 10011;
				vector<vector<int>> neiBo(iMax + 1);
				auto Add = [&](int cur, int next) {
					if ((next < 0) || (next > iMax)) { return; }
					neiBo[cur].emplace_back(next);
				};
				for (int i = 0; i <= iMax; i++) {
					Add(i, i + 1);
					Add(i, i - 1);
					if (0 == i % 5) { Add(i, i / 5); }
					if (0 == i % 11) { Add(i, i / 11); }
				}
				auto leve = CBFSLeve::Leve(neiBo, { x });
				return leve[y];
			}
};

单元测试

int x, y;
		TEST_METHOD(TestMethod1)
		{
			x = 3, y = 4;
			auto res = Solution().minimumOperationsToMakeEqual(x, y);
			AssertEx(1, res);
		}
		TEST_METHOD(TestMethod2)
		{
			x = 5, y = 4;
			auto res = Solution().minimumOperationsToMakeEqual(x, y);
			AssertEx(1, res);
		}
		TEST_METHOD(TestMethod3)
		{
			x = 4, y = 4;
			auto res = Solution().minimumOperationsToMakeEqual(x, y);
			AssertEx(0, res);
		}
		TEST_METHOD(TestMethod4)
		{
			x = 44, y = 4;
			auto res = Solution().minimumOperationsToMakeEqual(x, y);
			AssertEx(1, res);
		}
		TEST_METHOD(TestMethod5)
		{
			x = 20, y = 4;
			auto res = Solution().minimumOperationsToMakeEqual(x, y);
			AssertEx(1, res);
		}
		TEST_METHOD(TestMethod21)
		{			
			x = 26, y = 1;
			auto res = Solution().minimumOperationsToMakeEqual(x, y);
			AssertEx(3, res);
		}
		TEST_METHOD(TestMethod22)
		{
			x = 54, y = 2;
			auto res = Solution().minimumOperationsToMakeEqual(x, y);
			AssertEx(4, res);
		}
		TEST_METHOD(TestMethod23)
		{
			x = 25, y = 30;
			auto res = Solution().minimumOperationsToMakeEqual(x, y);
			AssertEx(5, 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++**实现。

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

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

相关文章

Linux项目实战——业务系统(后附百问网课程视频链接)

处理配置文件 一、main函数流程 初始化显示系统——>初始化输入系统——>初始化文字系统——>初始化页面系统——>业务系统 二、业务系统框架 1. 读取配置文件 2. 根据配置文件生成按钮、界面 3. 读取输入事件 4. 根据输入事件找到按钮 5. 调用按键的OnPressed函…

小程序开发怎么申请HTTPS证书?

小程序开发中申请SSL证书的流程包括选择信任可靠的SSL证书服务商、申请SSL证书、配置服务器、测试验证以等。以下将具体分析这个过程&#xff1a; 1、选择信任可靠的SSL证书服务商&#xff1a; 选择信任可靠的证书服务商&#xff0c;致命的证书服务商可以提供可靠的产品和完善…

【已解决】页面操作系统功能,诡异报错500nginx错误

【已解决】页面操作系统功能&#xff0c;诡异报错500nginx错误&#xff0c;后台没有任何报错信息 不知道啥原因 清理了浏览器缓存 也没有效果 还有一个表现情况&#xff0c;同样的操作&#xff0c;有时可以又是不行 因为报错ng的代理问题&#xff0c;检查了ng配置 后续经过同…

Unity强化工程 之 SpriteEditer SingleMode

本文仅作笔记学习和分享&#xff0c;不用做任何商业用途 本文包括但不限于unity官方手册&#xff0c;unity唐老狮等教程知识&#xff0c;如有不足还请斧正 因为unity不只是3d需要&#xff0c;还有2d游戏需要大量编辑处理图片素材&#xff0c;所以需要了解Sprite&#xff08;精灵…

Cesium初探-实体

在 Cesium 中&#xff0c;"实体"&#xff08;Entity&#xff09;是一个核心概念&#xff0c;它代表了可以在场景中渲染的任何东西&#xff0c;从简单的点、线、多边形到复杂的模型和图像。实体可以用来表示地理空间数据&#xff0c;如地标、轨迹、卫星轨道等。 以下…

【数据结构】栈的概念、结构和实现详解

本文来介绍一下数据结构中的栈&#xff0c;以及如何用C语言去实现。 1. 栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;它只允许在固定的一端进行插入和删除元素的操作。 进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。 栈中元素遵循后进先出…

PXE实现linux系统批量自动安装

实验环境&#xff1a; 1、RHEL7主机 2、主机图形化 3、配置网络可用 4、关闭vmware dhcp功能 一、实验环境准备 1、主机图形化 在安装安装RHEL7系统时&#xff0c;选择图形化安装&#xff0c;如果没有选择&#xff0c;可以在后面通过命令安装&#xff0c;如下&#xff1…

Pinia状态管理库

为了跨组件传递JWT令牌&#xff0c;我们就会利用Pinia状态管理库&#xff0c;它允许跨组件或页面共享状态。 使用Pinia步骤&#xff1a; 安装pinia&#xff1a;cnpm install pinia 在vue应用实例中使用pinia 在src/stores/token.js中定义store 在组件中使用store 1.在main.js文…

sql注入靶场sqli-labs常见sql注入漏洞详解

目录 sqli-labs-less1 1.less1普通解法 1.在url里面填写不同的值&#xff0c;返回的内容也不同&#xff0c;证明&#xff0c;数值是进入数据库进行比对了的&#xff08;可以被注入&#xff09; 2.判断最终执行的sql语句的后面还有内容吗&#xff0c;并且能够判断是字符型的拼接…

MySQL增删改查(基础)

1、. 新增&#xff08;Create&#xff09; 语法&#xff1a; INSERT [INTO] table_name[(column [, column] ...)] VALUES (value_list) [, (value_list)] ... 例子&#xff1a; -- 创建一张学生表 DROP TABLE IF EXISTS student; CREATE TABLE student (id INT,sn INT com…

电子琴——Arduino

音调有7个音调&#xff0c;分别是哆来咪发索莱西&#xff1b;如果用蜂鸣器来发出这七个音调就要分别设置这七个音调对应频率。 电子琴实现需要物品有&#xff0c;arduino开发板一个&#xff0c;按键7个&#xff0c;蜂鸣器1个&#xff0c;杜邦线若干 重点讲一下按键原理 按键开…

linux运维一天一个shell命令之vim详解

前言&#xff1a; 在日常运维工作中&#xff0c;掌握好 Vim 的使用可以极大地提高工作的效率。Vim 作为一个强大的文本编辑器&#xff0c;广泛应用于各种运维场景 一、定义 Vim 是一个非常强大的文本编辑器&#xff0c;在 Unix/Linux 环境中非常流行。它具有许多高级功能和快…

【神软大数据治理平台-高级动态SQL(接口开发)】

1、背景 业务部门需大数据平台按照所提需求提供企业数据接口&#xff0c;基于神软大数据治理平台-高级动态SQL功能&#xff0c;满足业务需求&#xff0c;如下&#xff1a; &#xff08;1&#xff09;业务系统需求&#xff1a; 输入&#xff1a; enterpriseName&#xff1a;…

【抖音卡片】在抖音私信的时候给对方发送抖音卡片链接

效果展示 效果说明 在默认情况下&#xff0c;给对方发送连接的时候是以文本的形式展示的可点击的超链接&#xff0c;但是经过处理之后可以将你发送的连接一样卡片的形式展示。 实现步骤 第一步&#xff1a;打开微信云托管 微信云托管 (qq.com)https://cloud.weixin.qq.com/c…

原装二手MSO5204B泰克DPO5204B混合信号示波器

泰克 MSO5204B混合信号示波器&#xff0c;2 GHz&#xff0c;4 16 通道&#xff0c;10 GS/s Tektronix MSO5204B 具有出色的信号保真度和高级分析和数学功能。 当今数据速率更快、时间裕度更严格&#xff0c;因此设计时需要具有出色信号采集性能和分析功能的示波器。Tektronix…

电源芯片负载调整率测试方法、原理以及自动化测试的优势-纳米软件

在芯片设计研发领域&#xff0c;负载调整率作为稳压电源芯片的关键性能指标&#xff0c;直接关系到芯片的稳定性和可靠性&#xff0c;因此其测试和优化显得尤为重要。以下是对负载调整率测试原理、方法以及使用ATECLOUD-IC芯片测试系统优势的进一步阐述&#xff1a; 负载调整率…

阿里云oss存储之定期删除

存储到OSS中文件基于存储费用的考虑需要将存储指定时间的文件进行删除,如果想实现定期删除,有以下方法可以处理,简单记录一下: 1、oss控制台 配置生命周期策略删除,如附件1截图 2、通过sdk,调用DeleteObject请求删除文件 如client.delete(ossdemo/some-not-exists-object); …

matlab的strel()函数的使用方法(OK)

这个函数 是形态学的结构元素 使用方法如下 SE strel(nhood) SE strel("diamond",r) SE strel("disk",r) SE strel("disk",r,n) SE strel("octagon",r) SE strel("line",len,deg) SE strel("rectangle",…

电脑运行库问题怎么修复?电脑运行库修复工具分享与实操

在我们日常使用电脑的过程中&#xff0c;经常会遇到一些因为运行库缺失或损坏而导致软件无法正常运行的问题。这些问题不仅影响工作效率&#xff0c;还可能导致数据丢失或程序崩溃。那么&#xff0c;电脑运行库怎么修复呢&#xff1f;本文将为您详细介绍如何使用运行库修复工具…

ETL数据集成丨将GreenPlum数据同步至Doris数仓

在当今数据驱动的时代&#xff0c;高效、可靠的数据集成成为企业数字化转型的关键一环。ETLCloud作为一款创新的数据集成平台&#xff0c;通过其强大的零代码配置能力&#xff0c;为企业提供了从数据抽取、转换到加载&#xff08;ETL&#xff09;的全链条解决方案&#xff0c;尤…