BZOJ 3210: 花神的浇花集会(切比雪夫距离)

版权声明:本文为博主原创文章,未经博主允许必须转载。 https://blog.csdn.net/qq_35950004/article/details/88954749

题目
切比雪夫距离是指王要从一个位子移至另一个位子需要走的步数。由于王可以往斜前或斜后方向移动一格,因此可以较有效率的到达目的的格子。
具体来说: ( x , y ) (x,y) ( X , Y ) (X,Y) 的切比雪夫距离为 M a x ( X x , Y y ) Max ( |X – x | , | Y – y | )
可以通过构造来将切比雪夫距离转化为曼哈顿距离:
大佬博客

( x , y ) > ( x y , x + y ) (x,y) -> (x-y,x+y)
( X , Y ) > ( X Y , X + Y ) (X,Y)->(X-Y,X+Y)
通过各种大小讨论可以得到一个简洁的式子。
X Y x + y + X + Y ( x + y ) = m a x ( 2 X , 2 Y ) |X-Y-x+y| + |X+Y - (x+y)| = max(2|X|,2|Y|)
于是切比雪夫距离就被转成了曼哈顿距离。

反之也有把曼哈顿距离转成切比雪夫距离然后扫描线之类的骚操作。
比如要你求一个点距离他曼哈顿距离小于k的点的数量不过这个好像不知道切比雪夫距离的人也能想到

注意这个题,转之后就是初中数学题,直接找中位数,但是如果转换后的坐标 ( x , y ) (x,y) 不满足 x , y x,y 同奇偶,实际上这个点是得不到的,那么还需要在邻域中搜一下。

#include<bits/stdc++.h>
#define maxn 100005
#define LL long long
using namespace std;

int n,x[maxn],y[maxn];

int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		int a,b;
		scanf("%d%d",&a,&b);
		x[i] = a - b , y[i] = a + b;
	}
	sort(x+1,x+1+n),sort(y+1,y+1+n);
	int mid = (1+n) >> 1;
	LL ans = 1e18;
	for(int i=-1;i<=1;i++)
		for(int j=-1;j<=1;j++)
			if(((x[mid]+i)^(y[mid]+j))%2==0){
				int u = x[mid] + i , v = y[mid] + j;
				LL sum = 0;
				for(int k=1;k<=n;k++) 
					sum += abs(x[k]-u) + abs(y[k]-v);
				ans = min(ans , sum);
			}
	printf("%lld\n",ans / 2);
}

猜你喜欢

转载自blog.csdn.net/qq_35950004/article/details/88954749