曼哈顿距离与切比雪夫距离

news/2024/11/18 11:47:11/文章来源:https://www.cnblogs.com/mathiter/p/18199399

曼哈顿距离与切比雪夫距离

距离 - OI Wiki (oi-wiki.org)已经说的比较清晰,提取要点和结论便于复习使用。

曼哈顿距离:\(d \left(\right. A , B \left.\right) = \left|\right. x_{1} - x_{2} \left|\right. + \left|\right. y_{1} - y_{2} \left|\right.\)

切比雪夫距离:\(d \left(\right. A , B \left.\right) = max \left(\right. \left|\right. x_{1} - x_{2} \left|\right. , \left|\right. y_{1} - y_{2} \left|\right. \left.\right)\)

曼哈顿距离与切比雪夫距离的相互转化

image-20240428170225637

结论:

  • 曼哈顿坐标系是通过切比雪夫坐标系旋转 \(\left(45\right)^{\circ}\) 后,再缩小到原来的一半得到的。
  • 将一个点 (𝑥,𝑦) 的坐标变为 (𝑥+𝑦,𝑥−𝑦) 后,原坐标系中的曼哈顿距离等于新坐标系中的切比雪夫距离
  • 将一个点 (𝑥,𝑦) 的坐标变为 \(\left(\right. \frac{x + y}{2} , \frac{x - y}{2} \left.\right)\) 后,原坐标系中的切比雪夫距离等于新坐标系中的曼哈顿距离

用处

  • 切比雪夫距离在计算的时候需要取max,往往不是很好优化,对于一个点,计算其他点到该的距离的复杂度为O(n)

  • 而曼哈顿距离只有求和以及取绝对值两种运算,我们把坐标排序后可以去掉绝对值的影响,进而用前缀和优化,可以把复杂度降为O(1)

  • 注意到切比雪夫转曼哈顿中除法如果向下取整可能会使答案不正确,所以考虑先不除以2,最后求完答案再除以2也是一样的

[曼哈顿距离与切比雪夫距离的互相转化 && 点对距离之和初步 - louis_11 - 博客园 (cnblogs.com)](https://www.cnblogs.com/qqq1112/p/15121123.html#:~:text=曼哈顿距离: %24Manhattandis (i%2C%24 %24j)%24 %24%3D%24 %24|x_i%24 %24-%24 %24x_j|%24,%24y1)

例题

1.https://leetcode.cn/problems/minimize-manhattan-distances/description/

题意:在二维平面上,给你若干个点。请你恰好移除一个点,返回移除后剩余任意两点之间的 最大曼哈顿 距离可能的 最小 值。

Solution:直接存入的转化为的切比雪夫距离,然后枚举删除的点,使用multiset维护x和y的所有取值,最大值就是当前剩余点中的max(最大x-最小x,最大y-最小y)

class Solution {#define pii pair<int,int>// #define int long longint cal(int x1,int x2,int y1,int y2){// cout<<x1<<" "<<x2<<" "<<y1<<" "<<y2<<endl;return max(abs(x1-x2),abs(y1-y2));}
public:int minimumDistance(vector<vector<int>>& points) {multiset<int>mstx;multiset<int>msty;multiset<pii>po;for(auto x:points){int y=x[0],w=x[1];int tx=y+w;int ty=y-w;po.insert({tx,ty});mstx.insert(tx);msty.insert(ty);}int ans=1e9;for(auto x:po){auto [y,w]=x;mstx.erase(mstx.find(y));msty.erase(msty.find(w));ans=min(ans,cal(*mstx.begin(),*mstx.rbegin(),*msty.begin(),*msty.rbegin()));mstx.insert(y);msty.insert(w);}return ans;}
};

曼哈顿转切比雪夫https://www.luogu.com.cn/problem/P5098

题意:给定若干二维平面的点,求其中两点的最大曼哈顿距离

Sol1:考虑存入变换后的坐标,然后直接最值相减取max即可

void solve(){cin>>n;vector<int>v1,v2;for(int i=0;i<n;i++){int x,y;cin>>x>>y;v1.push_back(x+y);v2.push_back(x-y);}int res1=*max_element(alls(v1))-*min_element(alls(v1));int res2=*max_element(alls(v2))-*min_element(alls(v2));cout<<max(res1,res2)<<endl;
}

Sol2:假如没学过这个套路,应该如何思考?

image-20240506124639455

  • 注:然后会发现以上两种思路的代码实现是一样的。

P3964 [TJOI2013] 松鼠聚会https://www.luogu.com.cn/problem/P3964

题意:有N个二位平面上的点,定义每一个点到其八连通的点的距离为1。选一个点,使得剩下所有点到该点的距离之和最小,求出这个距离之和。

Sol:本题是切比雪夫转曼哈顿来处理。注意到题目中给出的距离是切比雪夫距离的定义,要求距离之和我们考虑转化为曼哈顿以后利用排序和前缀和来处理。坐标转换的时候涉及除法,我们最后直接对答案除,不在中间计算过程除,防止精度损失。

具体实现:题意即为求切比雪夫距离之和最小,暴力的做法是\(O(N^2)\)的。考虑将切比雪夫距离转化为曼哈顿距离,我们将横纵坐标分开排序求前缀和,这样既可快速求出,以一个点为中心,其他点到这个点的曼哈顿距离之和。

  • 具体的做法是将两个坐标分开讨论,每次找到当前点在排序后数组的位置p。

  • 那么它前面的点坐标都小于当前点,累加的答案为\(p\times x[i]-sum_p\)

  • 后面的点的坐标都大于当前点,反过来累加答案,为\((sum_n-sum_p)-(n-p)\times x[i]\)

对所有的点都枚举一遍,取最小值即可,复杂度\(O(NlogN)\)

//切比雪夫转曼哈顿
void solve(){cin>>n;vector<pii>v1(n+1),v2(n+1);for(int i=1;i<=n;i++){int x,y;cin>>x>>y;v1[i]={x+y,i};v2[i]={x-y,i};}sort(alls(v1));sort(alls(v2));vector<int>ans(n+1);vector<int>pre1(n+1);vector<int>pre2(n+1);int s1=0,s2=0;for(int i=1;i<=n;i++){pre1[i]=pre1[i-1]+v1[i].fs;s1+=v1[i].fs;pre2[i]=pre2[i-1]+v2[i].fs;s2+=v2[i].fs;}for(int i=1;i<=n;i++){int c1=v1[i].fs*(i-1)-pre1[i-1]+(s1-pre1[i])-(n-i)*v1[i].fs;c1=abs(c1);int c2=v2[i].fs*(i-1)-pre2[i-1]+(s2-pre2[i])-(n-i)*v2[i].fs;c2=abs(c2);ans[v1[i].sec]+=c1;ans[v2[i].sec]+=c2;}int res=*min_element(alls(ans));cout<<res/2<<endl;
}

针对上题的总结:

image-20240506133548142

img

https://atcoder.jp/contests/abc351/tasks/abc351_e ABC351E

前置知识:坐标轴旋转后点的变换公式2.3.

逆变换公式建2.4

问题陈述

在坐标平面上有 \(N\) 个点 \(P_1, P_2, \ldots, P_N\) ,其中点 \(P_i\) 的坐标为 \((X_i, Y_i)\)
两点 \(A\)\(B\) 之间的距离 \(\text{dist}(A, B)\) 定义如下:

一只兔子最初位于点 \(A\)
位置为 \((x, y)\) 的兔子可以跳跃到 \((x+1, y+1)\)\((x+1, y-1)\)\((x-1, y+1)\)\((x-1, y-1)\)
\(\text{dist}(A, B)\) 被定义为从 \(A\) 点跳到 \(B\) 点所需的最少跳跃次数。
如果经过任意次数的跳跃都无法从点 \(A\) 到达点 \(B\) ,则设为 \(\text{dist}(A, B) = 0\)

计算总和 \(\displaystyle\sum_{i=1}^{N-1}\displaystyle\sum_{j=i+1}^N \text{dist}(P_i, P_j)\)

Sol:考虑这样的移动方式难以计算,我们使用旋转变换

将平面相对于原点旋转 \(45\) 度,并缩放 \(\sqrt{2}\) 倍。然后,原先位于 \((X,Y)\) 的点移动到 \((X+Y,X-Y)\)
\((x_i,y_i)\) 为经过此变换后各点 \(P_i\) 的坐标。那么, \(x_i=X_i+Y_i\)\(y_i=X_i-Y_i\)

  • 接下来,我们来看看 \(\text{dist}(A,B)\) 的定义是如何变化的。
    在最初的定义中,兔子可以从 \((X,Y)\) 跳转到 \((X+1,Y+1)\)\((X+1,Y-1)\)\((X-1,Y+1)\)\((X-1,Y-1)\)
    因此,经过变换后,它可以从 \((X+Y,X-Y)\) 跳到 \((X+Y+2,X-Y)\)\((X+Y,X-Y+2)\)\((X+Y,X-Y-2)\)\((X+Y-2,X-Y)\)

  • 替换 \(x=X+Y\)\(y=X-Y\) 后,可以从 \((x,y)\) 跳转到 \((x+2,y)\)\((x,y+2)\)\((x,y-2)\)\((x-2,y)\)
    \(A\) 到达 \(B\) 所需的最少跳转次数就是 \(\text{dist}(A,B)\) 的定义(如果无法到达,则为 \(0\) )。

下面,我们考虑变换后的问题。
也就是说,我们设 \(P_i=(x_i,y_i)\) ,定义 \(\text{dist}(A,B)\) ,并考虑和 \(\displaystyle\sum_{i=1}^{N-1}\displaystyle\sum_{j=i+1}^N \text{dist}(P_i,P_j)\) 与上述 \(\text{dist}(A,B)\) 的定义。
显然,这样得到的答案与原答案相同。

我们进一步将 \(\text{dist}(A,B)\) 视为 \(A=(x_1,y_1)\)\(B=(x_2,y_2)\) 。如果是 \(x_1\not\equiv x_2 \pmod{2}\)\(y_1\not\equiv y_2 \pmod{2}\) ,兔子就无法从 \(A\) 到达 \(B\) ,因此是 \(\text{dist}(A,B)=0\) 。否则,计算结果正好是曼哈顿距离的一半,即 \(\frac{1}{2}(\lvert x_1-x_2\rvert+\lvert y_1-y_2\rvert)\)

注意到所有 \(i\)\(x_i=y_i+2Y_i\equiv y_i \pmod{2}\)\(N\) 个点可以分为两组: \(x_i\)\(y_i\) 都是偶数,或者 \(x_i\)\(y_i\) 都是奇数。属于不同组的两个点 \(A\)\(B\)\(\text{dist}(A,B)=0\) ;属于同一组的两个不同点为 \(\text{dist}(A,B)=\frac{1}{2}(\lvert x_1-x_2\rvert+\lvert y_1-y_2\rvert)\)

不失一般性,我们考虑计算变换后的x都是偶数的情况,对于这样的点我们直接先对x排序,利用前缀和计算答案,这个计算方式在前面题目已经涉及。再给出一种方式,看贡献次数。假设下标从0开始,排序后后的元素\(x_j\)对前面的贡献是j*a[i],对后面的贡献是\(-a[i]\times(sz-j-1)\),两项合并加起来就是答案。

将同样的讨论应用于 \(y\) 坐标,可以求出 \(\displaystyle\sum_{i=1}^{\lvert E\rvert-1}\displaystyle\sum_{j=i+1}^{\lvert E\rvert} \text{dist}(P_{E_i},P_{E_j})\) ;将同样的讨论应用于奇数 \(x_i\)\(y_i\) 的组,可以求出最终的和。

对两组的坐标 \(x\)\(y\) 进行排序需要花费 \(O(N\log N)\) 时间,剩下的计算花费可以在 \(O(N)\) 时间内完成,所以这个问题总共可以在 \(O(N\log N)\) 时间内解决,速度足够快。因此,问题已经解决。

vector<int>a[4];
void solve(){cin>>n;for(int i=0;i<n;i++){int x,y;cin>>x>>y;if((x+y)%2){a[0].push_back(x+y);a[1].push_back(x-y);}else {a[2].push_back(x+y);a[3].push_back(x-y);}}for(int i=0;i<4;i++)sort(alls(a[i]));int ans=0;for(int i=0;i<4;i++){int sz=a[i].size();for(int j=0;j<sz;j++){ans+=a[i][j]*(2*j+1-sz);}}cout<<ans/2<<endl;
}

思路总结:坐标旋转转化为常规曼哈顿,注意到移动距离变成2倍,造成的影响有最后答案要除2以及横纵坐标之间必须mod2相同才可达。值得注意的是在这样变换下,一个点的横坐标和纵坐标一定是mod2同余的。

k维空间有n个点,求 k维曼哈顿距离最大值。首先从某ioi题目中得知:当k维曼哈顿转换成切比雪夫,变化的复杂度较高且不是线性。我们只能另寻他法。

https://vjudge.net/problem/POJ-2926

题意:给定若干五维点,求其中的两点之间的最大曼哈顿距离值

Sol:我们仔细对于二维的情况刨析,也就是前面的题目说没有套路的时候的思考方式,发现我们可以枚举正负号。比较关键的一点是减数与被减数在我们钦定符号后一定可以同构。

db a[N][6];
void solve(){
cin>>n;
for(int i=1;i<=n;i++){for(int j=0;j<5;j++){cin>>a[i][j];}
}db ans=0;
for(int i=0;i<32;i++){//初始化需要设置无穷,可能全是负的状态db mx=-1e13,mn=1e13;vector<db>sg(5);for(int j=4;j>=0;j--){if((i>>j)&1)sg[j]=1.0;else sg[j]=-1.0;}// cerr<<i<<endl;// for(auto x:sg)cerr<<x<<" ";// cerr<<endl;for(int j=1;j<=n;j++){db tmp=0;for(int k=0;k<5;k++){tmp+=sg[k]*a[j][k];}mx=max(mx,tmp);mn=min(mn,tmp);}ans=max(ans,mx-mn);
}
baoliu(ans,2);
}

k维曼哈顿距离的应用https://vjudge.net/problem/HDU-6435#author=GPT_zh

题意:n个主武器,m个副武器,每个武器有一个得分,和k个属性。现在你要最大化下面这个式子。img

也就是需要得分相加大,属性相差绝对值大,且两者和加起来大。注意满足的优先级。

int a[N][10];
int b[N][10];
void solve(){int k;cin>>n>>m>>k;for(int i=1;i<=n;i++){int x;cin>>x;a[i][0]=x;for(int j=2;j<k+2;j++)cin>>a[i][j];}for(int i=1;i<=m;i++){int x;cin>>x;b[i][1]=x;for(int j=2;j<k+2;j++)cin>>b[i][j];}ll ans=0;for(int s=0;s<(1<<(k+2));s++){ll tmp=0;ll mx1=-1e18,mn1=1e18;ll mx2=-1e18,mn2=1e18;for(int i=1;i<=n;i++){tmp=0;for(int j=0;j<k+2;j++){if((s>>j)&1)tmp+=a[i][j];else tmp-=a[i][j];}mx1=max(tmp,mx1);mn1=min(tmp,mn1);}for(int i=1;i<=m;i++){tmp=0;for(int j=0;j<k+2;j++){if((s>>j)&1)tmp+=b[i][j];else tmp-=b[i][j];}mx2=max(tmp,mx2);mn2=min(tmp,mn2);}ans=max({ans,mx2-mn1,mx1-mn2});}cout<<ans<<endl;
}

未完待续...

https://www.luogu.com/article/hxr7p6po

https://www.luogu.com.cn/problem/P4648

曼哈顿距离最小生成树 - GGBeng - 博客园 (cnblogs.com)

论一类平面点对曼哈顿距离问题 - 百度文库 (baidu.com)

浅谈信息学竞赛中的“0”和“1” - 道客巴巴 (doc88.com)

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

primethus

监控介绍 监控数据流程介绍监控优势 如果监控的是物理机,则用 Zabbix,Zabbix 在传统监控系统中,尤其是在服务器相关监控方面,占据绝对优势。甚至环境变动不会很频繁的情况下,Zabbix 也会比 Pometheus好使。但如果是云环境的话,除非是Zabbix玩的非常溜,可以做各种定制,否…

embedding

1 one-hot编码 首先讲讲one-hot编码,这种编码很简单。假设你有N个词,那么就直接创建一个N维度的向量,之后每个词在不同位置上取1来区分。N个词相当于在一个N维空间里,刚好N个单位向量。而且这些向量彼此正交 这种简单的表示方法存在几个问题:维度高:N个词有N个维度,所以…

美团一面问我i++跟++i的区别是什么

美团一面问我i++跟++i的区别是什么 面试官:“i++跟++i的区别是什么?” 我:“i++是先使用然后再执行+1的操作,++i是先执行+1的操作然后再去使用i” 面试官:“那你看看下面这段代码,运行结果是什么?” public static void main(String[] args) {int j = 0;for (int i = 0;…

成功实现FaceTime数据筛选,FaceTime蓝号检测,检测是否开通FaceTime功能的实现原理

FaceTime是苹果公司iOS和macOS(以前称Mac OS X或OS X)内置的一款视频通话软件,通过Wi-Fi或者蜂窝数据接入互联网,在两个装有FaceTime的设备之间实现视频通话。其要求通话双方均具有装有FaceTime的苹果设备,苹果ID以及可接入互联网的3G/4G/5G或者Wi-Fi网络。一、Windows电脑…

一文掌握:数据湖是什么?可不是数据仓库

一、什么是数据湖 数据湖(Data Lake)是指一个大型数据存储和处理系统,它能够存储各种类型和格式的数据,包括结构化数据、半结构化数据和非结构化数据。数据湖的目的是为了让企业可以更好地管理和利用大量的数据,以便进行数据分析、机器学习等工作。数据湖通常采用分布式计…

Django markdown 实现

一、安装markdown插件 pip install django-mdeditor pip install markdown二、在 settings 配置文件 INSTALLED_APPS 中添加 mdeditor:INSTALLED_APPS = [...mdeditor,]三、插入图片没有地址,针对django3.0+修改 frame 配置,settings.py设置如下: X_FRAME_OPTIONS = SAMEORI…

一款基于C#开发的通讯调试工具(支持Modbus RTU、MQTT调试)

前言 今天大姚给大家分享一款基于C#、WPF、Prism、MaterialDesign、HandyControl开发的通讯调试工具(支持Modbus RTU、MQTT调试,界面色彩丰富):Wu.CommTool。 工具特点工具界面色彩丰富。 支持Modbus RTU、MQTT服务器、MQTT客户端。 Modbus RTU自动解析数据帧。 智能防粘包…

20240518模拟赛

C240518A. 传送门(portal) 构造一个图使得点\(1\)到\(2\)的最短路正好有\(k\)条,使构造出的图点的个数\(N\le n_5\) 考虑\(k=2^t\)那么可以轻松构造出如下的图对于其他的情况可以考虑二进制拆分,如\(k=10\)时为了,使最短路长度固定加入点\(9\)对\(k=10^9\),只需构造\(80\)个…

『手撕Vue-CLI』添加帮助和版本号

前言 经过上一篇『手撕Vue-CLI』编码规范检查之后,手撕 Vue-CLI 已经进阶到了代码规范检查这一步,已经将基本的工程搭建好了,然后代码规范约束也已经加入了,并且将 nue-cli 指令绑定到了全局当中,可以在任何地方使用了。 正文 接下来这篇文章呢,就要来实现一下大多数的命…

ASE180N08-ASEMI低压N沟道MOS管ASE180N08

ASE180N08-ASEMI低压N沟道MOS管ASE180N08编辑:ll ASE180N08-ASEMI低压N沟道MOS管ASE180N08 型号:ASE180N08 品牌:ASEMI 批号:2024+ 沟道:N沟道 导通内阻RDS(ON)Max:4.0mΩ 启动电压:2V-4V 最大漏源电流(Id):180A 漏源击穿电压(VRM):80V 正向电压:1.3V 特性:低…

垂直关系转化思维导图

线线、线面、面面垂直关系转化思维导图前言 使用方法:如果想得到更好的显示效果,可以点击全屏按钮,已经实现电脑端、手机端的适配,效果很好;电视端没有实现适配,Ipad端的适配没有测试; 思维结构图全屏 相关说明 内容继续编辑完善中,源文件存放在 draw.io 上。