【键值皆有序map 线段树 数学 】100240. 最小化曼哈顿距离

本文涉及知识点

键值皆有序map 线段树 数学

LeetCode100240. 最小化曼哈顿距离

给你一个下标从 0 开始的数组 points ,它表示二维平面上一些点的整数坐标,其中 points[i] = [xi, yi] 。
两点之间的距离定义为它们的曼哈顿距离。
请你恰好移除一个点,返回移除后任意两点之间的 最大 距离可能的 最小 值。
示例 1:
输入:points = [[3,10],[5,15],[10,2],[4,4]]
输出:12
解释:移除每个点后的最大距离如下所示:

  • 移除第 0 个点后,最大距离在点 (5, 15) 和 (10, 2) 之间,为 |5 - 10| + |15 - 2| = 18 。
  • 移除第 1 个点后,最大距离在点 (3, 10) 和 (10, 2) 之间,为 |3 - 10| + |10 - 2| = 15 。
  • 移除第 2 个点后,最大距离在点 (5, 15) 和 (4, 4) 之间,为 |5 - 4| + |15 - 4| = 12 。
  • 移除第 3 个点后,最大距离在点 (5, 15) 和 (10, 2) 之间的,为 |5 - 10| + |15 - 2| = 18 。
    在恰好移除一个点后,任意两点之间的最大距离可能的最小值是 12 。
    示例 2:
    输入:points = [[1,1],[1,1],[1,1]]
    输出:0
    解释:移除任一点后,任意两点之间的最大距离都是 0 。

提示:
3 <= points.length <= 105
points[i].length == 2
1 <= points[i][0], points[i][1] <= 108

数学

假定p1到p2的距离最大,则如果不删除p1或p2,最大距离一定不会变小。
我们只需要找到任意一对p1、p2,分别尝试删除p1和p2的最大距离。问题就转化成求:最大曼哈顿距离。
最大曼哈顿距离,应该有公式和模板。但我没有。这两天在研究线段树,就用线段树。结果11:59才完成编码。赛下,调试了一个小时才搞定。

线段树

将points 按x排序,i表示第一个点,j表示第二个点。则xi <= xj恒成立。只需要考虑yi和yj的大小。
{ x j − x i + y j − y i = ( x j + y j ) − ( x i + y i ) y i < = y j x j − x i + y i − y j = ( x j − y j ) − ( x i − y i ) y i > = y j \begin{cases} xj-xi+yj-yi = (xj+yj)-(xi+yi) && yi <= yj \\ xj-xi+yi-yj = (xj-yj)-(xi-yi) && yi >= yj \\ \end{cases} {xjxi+yjyi=(xj+yj)(xi+yi)xjxi+yiyj=(xjyj)(xiyi)yi<=yjyi>=yj
我们只需要计算 (xi+yi)和(xi-yi) 的最小值。用两棵最小树,分别记录最小值,单点更新,区间查找。难点:先要离散化,否则空间复杂度会超。

键值皆有序映射

情况一: yi <= yj
(xi+yi)和yj都越小越好,故键yj 升序,值(xi+yi)降序,如果冲突,淘汰键大的。
情况二:yi >= yj
(xi- yi) 越小越好,yj越大越好。故键yj升序,值(xi- yi)升序。发生冲突,淘汰键小的。

我看题解才知道的

切比雪夫距离(Chebyshev Distance) 在二维空间中,切比雪夫距离是通过计算两个点在各个坐标轴上的差值的绝对值中的最大值来衡量它。
曼哈顿距离在坐标轴旋转 45 度后与切比雪夫距离等价。

代码

线段树实现

class CDiscretize //离散化
{
public:
	CDiscretize(vector<int> nums)
	{
		sort(nums.begin(), nums.end());
		nums.erase(std::unique(nums.begin(), nums.end()), nums.end());
		m_nums = nums;
		for (int i = 0; i < nums.size(); i++)
		{
			m_mValueToIndex[nums[i]] = i;
		}
	}
	int operator[](const int value)const
	{
		auto it = m_mValueToIndex.find(value);
		if (m_mValueToIndex.end() == it)
		{
			return -1;
		}
		return it->second;
	}
	int size()const
	{
		return m_mValueToIndex.size();
	}
	vector<int> m_nums;
protected:	
	unordered_map<int, int> m_mValueToIndex;
};

template<class TSave, class TRecord>
class CSingUpdateLineTree
{
public:
	CSingUpdateLineTree(int iEleSize, TSave tDefautl) :m_iEleSize(iEleSize), m_vSave(iEleSize * 4, tDefautl) {

	}
	void Update(int index, TRecord update) {
		Update(1, 1, m_iEleSize, index + 1, update);
	}
	void Query(int leftIndex, int leftRight) {
		Query(1, 1, m_iEleSize, leftIndex + 1, leftRight + 1);
	}
	void Init() {
		Init(1, 1, m_iEleSize);
	}
	const int m_iEleSize;
protected:
	void Init(int iNodeNO, int iSaveLeft, int iSaveRight)
	{
		if (iSaveLeft == iSaveRight) {
			OnInit(m_vSave[iNodeNO], iSaveLeft);
			return;
		}
		const int mid = iSaveLeft + (iSaveRight - iSaveLeft) / 2;
		Init(iNodeNO * 2, iSaveLeft, mid);
		Init(iNodeNO * 2 + 1, mid + 1, iSaveRight);
		OnUpdateParent(m_vSave[iNodeNO], m_vSave[iNodeNO * 2], m_vSave[iNodeNO * 2 + 1], iSaveLeft, iSaveRight);
	}
	void Query(int iNodeNO, int iSaveLeft, int iSaveRight, int iQueryLeft, int iQueryRight) {
		if ((iSaveLeft >= iQueryLeft) && (iSaveRight <= iQueryRight)) {
			OnQuery(m_vSave[iNodeNO]);
			return;
		}
		if (iSaveLeft == iSaveRight) {//没有子节点
			return;
		}
		const int mid = iSaveLeft + (iSaveRight - iSaveLeft) / 2;
		if (mid >= iQueryLeft) {
			Query(iNodeNO * 2, iSaveLeft, mid, iQueryLeft, iQueryRight);
		}
		if (mid + 1 <= iQueryRight) {
			Query(iNodeNO * 2 + 1, mid + 1, iSaveRight, iQueryLeft, iQueryRight);
		}
	}
	void Update(int iNodeNO, int iSaveLeft, int iSaveRight, int iUpdateNO, TRecord update) {
		if (iSaveLeft == iSaveRight)
		{
			OnUpdate(m_vSave[iNodeNO], iSaveLeft, update);
			return;
		}
		const int mid = iSaveLeft + (iSaveRight - iSaveLeft) / 2;
		if (iUpdateNO <= mid) {
			Update(iNodeNO * 2, iSaveLeft, mid, iUpdateNO, update);
		}
		else {
			Update(iNodeNO * 2 + 1, mid + 1, iSaveRight, iUpdateNO, update);
		}
		OnUpdateParent(m_vSave[iNodeNO], m_vSave[iNodeNO * 2], m_vSave[iNodeNO * 2 + 1], iSaveLeft, iSaveRight);
	}
	virtual void OnInit(TSave& save, int iSave) = 0;
	virtual void OnQuery(TSave& save) = 0;
	virtual void OnUpdate(TSave& save,int iSaveLeft, const TRecord& update) = 0;
	virtual void OnUpdateParent(TSave& par, const TSave& left, const TSave& r, int iSaveLeft, int iSaveRight) = 0;
	vector<TSave> m_vSave;
};


template<class TSave=pair<int,int>, class TRecord =int>
class CMyLineTree : protected CSingUpdateLineTree<TSave, TRecord>
{
public:
	CMyLineTree(CDiscretize& dis,int iEleSize) : m_dis(dis),CSingUpdateLineTree<TSave, TRecord>(iEleSize,std::make_pair(1e9,-1)) {

	}
	void Update(int y, TRecord update) {
		CSingUpdateLineTree<TSave, TRecord>::Update(m_dis[y],update);
	}
	void QueryLessEqual(int y) {
		m_prMin = { 1e9,-1 };
		CSingUpdateLineTree<TSave, TRecord>::Query(0, m_dis[y]);
	}
	void QueryMoreEqual(int y) {
		m_prMin = { 1e9,-1 };
		CSingUpdateLineTree<TSave, TRecord>::Query(m_dis[y], m_dis.size()-1);
	}
	pair<int, int> m_prMin = { 1e9,-1 };
protected:
	virtual void OnInit(TSave& save, int iSave) override
	{
	}
	virtual void OnQuery(TSave& save) override
	{
		if (save < m_prMin) {
			m_prMin = save;
		}	
	}
	virtual void OnUpdate(TSave& save, int iSaveLeft,const TRecord& update) override
	{
		TSave tmp = { update,m_dis.m_nums[iSaveLeft - 1] };
		save = min(save,tmp);
	}
	virtual void OnUpdateParent(TSave& par, const TSave& left, const TSave& r, int iSaveLeft, int iSaveRight) override
	{
		par = min(left, r);
	}	
	CDiscretize& m_dis;
}; 
class Solution {
public:
	int minimumDistance(vector<vector<int>>& points) {
		sort(points.begin(), points.end(), [](const auto& v1, const auto& v2) {return v1[0] < v2[0]; });
		auto [tmp, i1, i2] = Max(points);
		auto pts1 = points, pts2 = points;
		pts1.erase(pts1.begin() + i1);
		pts2.erase(pts2.begin() + i2);
		auto [m1, tmp1, tmp2] = Max(pts1);
		auto [m2, tmp3, tmp4] = Max(pts2);
		return min(m1, m2);
	}
	std::tuple<int, int, int> Max(const vector<vector<int>>& pts) {
		vector<int> ys;
		for (const auto& pt : pts) {
			ys.emplace_back(pt[1]);
		}
		CDiscretize dis(ys);
		CMyLineTree mXAndY(dis,dis.size()), mXSubY(dis, dis.size());
		const int n = pts.size();
		int iRet = -1e9,i2;
		std::pair<int, int> xy;
		for (int i = 1; i < n; i++) {
			mXAndY.Update(pts[i - 1][1], pts[i - 1][0] + pts[i - 1][1]);
			mXSubY.Update(pts[i - 1][1], pts[i - 1][0] - pts[i - 1][1]);
			mXAndY.QueryLessEqual(pts[i][1]);
			const int iDis1 = pts[i][0] + pts[i][1] - mXAndY.m_prMin.first;
			if (iDis1 > iRet) {
				iRet = iDis1;
				xy = { mXAndY.m_prMin.first- mXAndY.m_prMin.second, mXAndY.m_prMin.second };
				i2 = i;
			}
			mXSubY.QueryMoreEqual(pts[i][1]);
			const int iDis2 = pts[i][0] - pts[i][1] - mXSubY.m_prMin.first;
			if (iDis2 > iRet) {
				iRet = iDis2;
				xy = { mXSubY.m_prMin.first + mXSubY.m_prMin.second, mXSubY.m_prMin.second };
				i2 = i;
			}
		}
		int i1 = 0;
		for (; (xy.first != pts[i1][0]) || (xy.second != pts[i1][1]);i1++);
		return { iRet,i1,i2 };
	}
};

测试用例

template<class T>
void Assert(const T& t1, const T& t2)
{
	assert(t1 == t2);
}

template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{
	if (v1.size() != v2.size())
	{
		assert(false);
		return;
	}
	for (int i = 0; i < v1.size(); i++)
	{
		Assert(v1[i], v2[i]);
	}

}

int main()
{
	vector<vector<int>> points;
	{
		points = { {9,8},{1,8},{3,1},{9,1},{7,7},{3,6} };
		auto res = Solution().minimumDistance(points);
		Assert(13, res);
	}
	{
		points = { {3,10},{5,15},{10,2},{4,4} };
		auto res = Solution().minimumDistance(points);
		Assert(12, res);
	}
	{
		points = { {3,2},{3,9},{7,10},{4,4},{8,10},{2,7} };
		auto res = Solution().minimumDistance(points);
		Assert(10, res);
	}
	
	{
		points = { {1,1},{1,1},{1,1},{1,1} };
		auto res = Solution().minimumDistance(points);
		Assert(0, res);
	}
	
	//CConsole::Out(res);
}

键值皆有需map

template<class _Kty, class _Ty, bool bValueAsc, bool bOutSmallKey>
class COrderValueMap
{
public:
	void Add(_Kty key, _Ty value)
	{
		if (bOutSmallKey)
		{
			if (bValueAsc)
			{
				AddOutSmall(key, value, std::less_equal<_Ty>(), std::greater_equal<_Ty>());
			}
			else
			{
				AddOutSmall(key, value, std::greater_equal<_Ty>(), std::less_equal<_Ty>());
			}
		}
		else
		{
			if (bValueAsc)
			{
				AddNotOutSmall(key, value, std::greater_equal<_Ty>(), std::less_equal<_Ty>());
			}
			else
			{
				AddNotOutSmall(key, value, std::less_equal<_Ty>(), std::greater_equal<_Ty>());
			}
		}
	};
	std::map<_Kty, _Ty> m_map;
protected:
	template<class _Pr1, class _Pr2>
	void AddOutSmall(_Kty key, _Ty value, _Pr1 pr1, _Pr2 pr2)
	{
		auto it = m_map.lower_bound(key);
		if ((m_map.end() != it) && pr1(it->second, value))
		{
			return;//被旧值淘汰
		}
		auto ij = it;
		while (it != m_map.begin())
		{
			--it;
			if (pr2(it->second, value))
			{
				it = m_map.erase(it);
			}
			else
			{
				break;
			}
		}
		m_map[key] = value;
	}
	template<class _Pr1, class _Pr2>
	void AddNotOutSmall(_Kty key, _Ty value, _Pr1 pr1, _Pr2 pr2)
	{
		auto it = m_map.upper_bound(key);
		if ((m_map.begin() != it) && pr1(std::prev(it)->second, value))
		{
			return;//被淘汰
		}
		auto ij = it;
		for (; (m_map.end() != ij) && pr2(ij->second, value); ++ij);
		m_map.erase(it, ij);
		m_map[key] = value;
	};

};


class Solution {
public:
	int minimumDistance(vector<vector<int>>& points) {
		sort(points.begin(), points.end(), [](const auto& v1, const auto& v2) {return v1[0] < v2[0]; });
		auto [tmp, i1, i2] = Max(points);
		auto pts1 = points, pts2 = points;
		pts1.erase(pts1.begin() + i1);
		pts2.erase(pts2.begin() + i2);
		auto [m1, tmp1, tmp2] = Max(pts1);
		auto [m2, tmp3, tmp4] = Max(pts2);
		return min(m1, m2);
	}
	std::tuple<int, int, int> Max(const vector<vector<int>>& pts) {
		COrderValueMap<int, int, false, false> mXAndY;
		COrderValueMap<int, int, true, true> mXSubY;
		const int n = pts.size();
		int iRet = -1e9,i2;
		for (int i = 1; i < n; i++) {
			mXAndY.Add(pts[i - 1][1], pts[i - 1][0] + pts[i - 1][1]);
			mXSubY.Add(pts[i - 1][1], pts[i - 1][0] - pts[i - 1][1]);
			auto it1 = mXAndY.m_map.upper_bound(pts[i][1]);
			if (mXAndY.m_map.begin() != it1 ) {
				--it1;
				const int iDis1 = pts[i][0] + pts[i][1] - it1->second;
				if (iDis1 > iRet) {
					iRet = iDis1;
					i2 = i;
				}
			}
			auto it2 = mXSubY.m_map.lower_bound(pts[i][1]);
			if (it2 != mXSubY.m_map.end()) {
				const int iDis2 = pts[i][0] - pts[i][1] - it2->second;
				if (iDis2 > iRet) {
					iRet = iDis2;
					i2 = i;
				}
			}
		}
		int i1 = -1,iMinDis=-1;
		for (int i = 0; i < n; i++) {
			const int curDis = abs(pts[i][0] - pts[i2][0]) + abs(pts[i][1] - pts[i2][1]);
			if (curDis > iMinDis) {
				iMinDis = curDis;
				i1 = i;
			}
		}
		return { iRet,i1,i2 };
	}
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【蓝桥杯第十三届省赛B】(部分详解)

九进制转十进制 #include <iostream> #include<math.h> using namespace std; int main() {cout << 2*pow(9,3)0*pow(9,2)2*pow(9,1)2*pow(9,0) << endl;return 0; }顺子日期 #include <iostream> using namespace std; int main() {// 请在此…

SOC内部集成网络MAC外设+ PHY网络芯片方案:MII/RMII 接口与 MDIO 接口

一. 简介 本文来了解一下常用的一种网络硬件方案&#xff1a;SOC内部集成网络MAC外设 PHY网络芯片方案。 其中涉及的 MII接口&#xff0c;RMII接口&#xff08;MII接口与RMII接口二选一&#xff09;&#xff0c;MDIO接口&#xff0c;RJ45。 二. MII/RMII 接口&#xff0c;M…

unity学习(74)——服务器Dispose异常

1.返回的1 2 11是怪物初始化&#xff0c;源代码中也没有 2. 3.客户端中的网络连接初始化如下&#xff1a; 4.不是因为超时&#xff0c;设置10s为超时期限后&#xff0c;客户端和服务器有时依然会报错&#xff01; 5.我感觉就是update中发包给弄坏的&#xff01; 6.不在“帧”…

【prometheus】k8s集群部署Grafana安装并接入Promethues数据源

目录 一、概述 1.1 优点 1.2 特点 二、grafana部署 三、grafana接入Promethues数据源 四、grafana可视化展示物理节点指标数据 五、grafana可视化展示k8s组件指标数据 5.1 kube-state-metrics简介 5.2 安装kube-state-metrics组件 一、概述 Grafana是一款用Go语言开发…

CodeTON Round 8 D. Learning to Paint 【DP求前k大】

D. Learning to Paint 题意 有一个 n n n 个格子长度的条带&#xff0c;格子从左到右编号为 1 → n 1 \rarr n 1→n&#xff0c;可以选择若干子段&#xff08;或不选&#xff09;的格子&#xff0c;给定一个二维数组 a a a 每选择一个 [ l i , r i ] [l_i,r_i] [li​,ri​…

5G无线接入网和接口协议

**部分笔记** 4.3无线协议架构 NR无线协议分为两个平面&#xff1a;用户面和控制面。 用户面&#xff08;UP&#xff09;:协议栈及用户数据采用的协议 控制面(Control Plane&#xff0c;CP)协议栈即系统的控制信令传输采用的协议簇。 虚线标注的是信令数据的流向。一个UE在…

[计算机效率] 文件加密工具:Lockdir

3.11 文件加密工具&#xff1a;Lockdir Lockdir是一款安全性高、使用简单、体积极小的便携式文件夹加密器&#xff0c;无需安装&#xff0c;一键加密&#xff0c;一键解密&#xff0c;加密算法高&#xff0c;是优秀的加密工具。其主要特点包括&#xff1a; 加密操作简易&#…

遥感动态监测技术

很多人对动态监测和动态检测两个名词有疑惑。我们可以这样理解&#xff0c;动态监测是一个广义的名词&#xff0c;泛指数据预处理、变化信息发现与提取、变化信息挖掘与应用等&#xff0c;以对整个流程的叙述。动态检测是一个狭义的名词&#xff0c;主要指部分数据预处理、变化…

Python | Leetcode Python题解之第4题寻找两个正序数组的中位数

题目&#xff1a; 题解&#xff1a; class Solution:def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:def getKthElement(k):"""- 主要思路&#xff1a;要找到第 k (k>1) 小的元素&#xff0c;那么就取 pivot1 nums1[k…

需要给Word文档中的汉字注音,拼音要在汉字的右边 要怎么操作?两种方法一学就会

在Word文档中&#xff0c;为字体添加拼音是一个常见的需求&#xff0c;特别是在处理包含生僻字或需要标注拼音的文本时。下面&#xff0c;我们将详细介绍如何在Word文档中将拼音加到字体的右边。 方法一&#xff1a;使用“汇帮注音大师”给汉字加拼音加到右边 第一步&#xf…

快速排序---算法

1、算法概念 快速排序&#xff1a;通过一趟排序将待排记录分隔成独立的两部分&#xff0c;其中一部分记录的数据均比另一部分的数据小&#xff0c;则可分别对这两部分记录继续进行排序&#xff0c;以达到震哥哥序列有序。 快速排序的最坏运行情况是O()&#xff0c;比如说顺序数…

整数删除,蓝桥杯训练题

题目描述: 给定一个长度为 N 的整数数列&#xff1a;A1,A2,…,AN。 你要重复以下操作 K 次&#xff1a; 每次选择数列中最小的整数&#xff08;如果最小值不止一个&#xff0c;选择最靠前的&#xff09;&#xff0c;将其删除&#xff0c;并把与它相邻的整数加上被删除的数值。 …

【前端面试3+1】06继承方式及优缺点、缓存策略、url输入到渲染全过程、【二叉树中序遍历】

一、继承有哪些方式&#xff1f;以及优缺点 继承的方式包括原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承和组合式继承。 1.原型链继承&#xff1a; 实现方式&#xff1a;将子类的原型指向父类的实例来实现继承。优点&#xff1a;简单易懂&#xff0c;代码量少。…

linux 一些命令

文章目录 linux 一些命令fdisk 磁盘分区parted 分区文件系统mkfs 格式化文件系统fsck 修复文件系统 mount 挂载swap 交换分区清除linux缓存df du 命令raid 命令基本原理硬raid 和 软raid案例raid 10 故障修复&#xff0c;重启与卸载 lvm逻辑卷技术LVM的使用方式LVM 常见名词解析…

wavedec2函数及使用

在MATLAB中&#xff0c;进行小波分解及其逆运算是处理图像的一种常见方法&#xff0c;尤其适用于图像分析、压缩和去噪等场景。wavedec2函数可以对二维信号&#xff08;例如图像&#xff09;进行多级小波分解&#xff0c;而waverec2函数则用于进行相应的逆运算。以下是如何使用…

【树状数组专题】【蓝桥杯备考训练】:数星星、动态求连续区间和、一个简单的整数问题、一个简单的整数问题2【已更新完成】

目录 1、数星星&#xff08;《信息学奥赛一本通》 & ural 1028&#xff09; 思路&#xff1a; 基本思路&#xff1a; 树状数组经典三函数&#xff1a; 1、lowbit()函数 2、query()函数 3、add()函数 最终代码&#xff1a; 2、动态求连续区间和&#xff08;《信息学奥赛一本…

笔记本三屏异显方案——更新中,是否能够在FPGA上实现,淘宝购物的价格太贵

三屏是&#xff08;笔记本电脑屏幕&#xff0c;两个显示器屏幕&#xff09;&#xff0c;异显是采用屏幕的扩展功能&#xff0c;这样能够左边看视频文章&#xff0c;右边control cv代码。 一、 电脑有一个HDMI口的时候&#xff0c;只需要买一个TypeC&#xff08;雷电接口&#x…

ruoyi-nbcio-plus基于vue3的flowable任务监听器的升级修改

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://122.227.135.243:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a…

基于Springboot点餐平台网站

采用技术 基于Springboot点餐平台网站的设计与实现~ 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBootMyBatis 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 页面展示效果 菜品评价管理 订单管理 前台首页 管理员登录 用户管理 菜品分…

MATLAB小波包分解及逆向操作

MATLAB代码 % 载入图像 grayImg imread(lena256.bmp); % 替换为你的图像路径% 选择小波函数和分解级别 waveletFunction db1; level 2;% 执行WPT正向分解 wp wpdec2(double(grayImg), level, waveletFunction);% 从小波包分解中重建图像&#xff08;逆向运算&#xff09; r…