卧薪尝胆,厚积薄发。
      
    
            TJOI2013 松鼠聚会
        
        
        Description:
给
$n$
个点,选一个点使得这个点到其他所有点的切比雪夫距离之和最小。
$1\le n \le 100000$
Solution:
首先把切比雪夫距离转化成曼哈顿距离
$(x,y)\to (\frac {x+y}2,\frac{x-y}2)$
,这样在原坐标系下的切比雪夫距离就是新坐标系下的曼哈顿距离,然后答案就是
$\begin{align}\sum_{i=1}^n|x_i'-x|+|y_i'-y|\end{align}$
,然后我们把
$x$
和
$y$
分别来看,就变成了
$\begin{align}\sum_{i=1}^n|x_i'-x|+\sum_{i=1}^n|y'_i-y|\end{align}$
,然后依次枚举每个点在
$x$
和
$y$
序列中二分他的位置,用前缀和求距离就行了。
$double$
会掉精度(掉成爆零),所以最后再除二。
Code:
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int n;
#define MAXN 100010
typedef long long ll;
struct point
{
	ll x,y;
}p[MAXN],s[MAXN];
ll x[MAXN],y[MAXN];
ll sumx[MAXN],sumy[MAXN];
int main()
{
	scanf("%d",&n);
	for(int i = 1;i <= n;++i)scanf("%lld%lld",&p[i].x,&p[i].y);
	for(int i = 1;i <= n;++i)
	{
		s[i].x = x[i] = p[i].x + p[i].y;
		s[i].y = y[i] = p[i].x - p[i].y;
	}
	sort(x + 1,x + 1 + n);
	for(int i = 1;i <= n;++i)sumx[i] = sumx[i - 1] + x[i];
	sort(y + 1,y + 1 + n);
	for(int i = 1;i <= n;++i)sumy[i] = sumy[i - 1] + y[i];
	ll ans = 0x3f3f3f3f3f3f3f3f;
	int p;
	for(int i = 1;i <= n;++i)
	{
		ll res = 0;
		p = lower_bound(x + 1,x + 1 + n,s[i].x) - x;
		res += p * s[i].x - sumx[p] + sumx[n] - sumx[p] - (n - p) * s[i].x;
		p = lower_bound(y + 1,y + 1 + n,s[i].y) - y;
		res += p * s[i].y - sumy[p] + sumy[n] - sumy[p] - (n - p) * s[i].y;
		ans = min(ans,res);
	}
	cout << ans / 2 << endl;
	return 0;
}
 In tag:
数学-曼哈顿距离与切比雪夫距离
          In tag:
数学-曼哈顿距离与切比雪夫距离 
          
        
        Copyright © 2020
        
          wjh15101051
        
      
      ღゝ◡╹)ノ♡
     Date: Tue Sep 11 15:53:25 CST 2018
          Date: Tue Sep 11 15:53:25 CST 2018
           In Category:
          In Category:
           
         Timeline
            Timeline
           About
            About
           Toolbox
            Toolbox
           Friends
              Friends