1012 - 曼哈顿距离&切比雪夫距离

什么是切比雪夫距离?什么是曼哈顿距离?

傻傻分不清,没关系,看:

曼哈顿距离

设平面空间内存在两点,它们的坐标为(x1,y1),(x2,y2)

则dis=|x1−x2|+|y1−y2|

即两点横纵坐标差之和

切比雪夫距离

设平面空间内存在两点,它们的坐标为(x1,y1),(x2,y2)

则dis=max(|x1−x2|,|y1−y2|)

即两点横纵坐标差的最大值

比如这个图,A,B两点的曼哈顿距离就是dis=(2-(-2))+(3-0)=7

切比雪夫距离就是dis=max(2-(-2),(3-0))=4

 

既然都提到这两个距离了,就免不了要讲讲它们的相互转化

将一个点(x,y)的坐标变为(x+y,x−y)后,原坐标系中的曼哈顿距离 = 新坐标系中的切比雪夫距离

将一个点(x,y)的坐标变为(x+y)/2,(x-y)/2后,原坐标系中的切比雪夫距离 = 新坐标系中的曼哈顿距离

这个证明也很容易,有兴趣的同学可以来皮一下

我就不在这里赘述了

 

然而有什么用呢??这么多奇奇怪怪的定义,真是让人摸不着头脑

但事实上,可有用了呢

切比雪夫距离由于要求max 很多时候不是很好优化,对于一个点,计算其他点到该的距离的复杂度为O(n)(因为要枚举)

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

而有一个细节需要注意一下:

在切比雪夫距离转曼哈顿距离的时候,坐标本是要除以2的,但考虑到精度的问题,我们一般都会将除以2 这一步操作放到最后
这样也是正确的,形象的理解可以说成,曼哈顿坐标系是通过切比雪夫坐标系旋转45度后,再缩小到原来的一半得到的。

 

是不是手痒痒了??来吧,练一道入门题 松鼠聚会(TJOI 2013)

 

 

#include<bits/stdc++.h>
#define ll long long 
#define N 100009
#define in read()
using namespace std;
inline int read(){
	char ch;int f=1,res=0;
	while((ch=getchar())<'0'||ch>'9') if(ch=='-') f=-1;
	while(ch>='0'&&ch<='9'){
		res=(res<<3)+(res<<1)+ch-'0';
		ch=getchar();
	}
	return f==1?res:-res;
}
ll ans=1ll<<50ll,sumx[N],sumy[N];//一开始ans又初始小了~~~~~悲伤
int n,x[N],y[N],xx[N],yy[N];
ll solve(int now){//现在要到 n 的家里去 
	ll res=0;
	int pos=lower_bound(xx+1,xx+n+1,x[now])-xx;
	res+=1ll*pos*x[now]-sumx[pos]+sumx[n]-sumx[pos]-1ll*(n-pos)*x[now];
	
	pos=lower_bound(yy+1,yy+n+1,y[now])-yy;
	res+=1ll*pos*y[now]-sumy[pos]+sumy[n]-sumy[pos]-1ll*(n-pos)*y[now];
	
	return res;
}
int main(){
	n=in;
	int i,j,k;
	for(i=1;i<=n;++i) {
		int a=in;int b=in;
		x[i]=xx[i]=a+b;
		y[i]=yy[i]=a-b;
	}
	
	sort(xx+1,xx+n+1);
	sort(yy+1,yy+n+1);
	
	for(i=1;i<=n;++i){
		sumx[i]=sumx[i-1]+xx[i];
		sumy[i]=sumy[i-1]+yy[i];
	}
	
	for(i=1;i<=n;++i)
		ans=min(ans,solve(i));
		

	cout<<ans/2;
	return 0;
}

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值