2388 首都(曼哈顿距离与切比雪夫距离互转)

在平面上有n个整点(横纵坐标都是整数)
牛牛想找到一个整点,使得这个点,到所有点的距离之和最小。
两个点的距离定义为从一个点走到另一个点的最小步数。
其中每步可以走向相邻8个点(上,下,左,右,左上,左下,右上,右下,类似国际象棋中的王)走一步。
输出这个最小的距离之和。
和这个点选择的方案数。(即有多少个点,可以达到这个最小的距离)
对于100%的数据,1 <= n <= 100000,|x|, |y| <= 1000000000
对于40%的数据,1 <= n <= 100,|x|, |y| <= 100
对于以上每部分数据,都有50%的数据n是奇数。
注意数据范围是x和y的绝对值,x和y可以是负数。
输入
第一行一个整数n
接下来n行,每行两个整数x, y。描述一个点。
输出
第一行输出最小的距离之和。
第二行输出有多少个点,可以达到这个最小距离。
输入样例
4
2 1
1 2
0 1
1 0
输出样例
4
5
曼哈顿距离与切比雪夫距离及其相互转
语法知识:
n&1:
当n为奇数:1
当n为偶数:0
n^1:
当n为奇数:n-1
当n为偶数:n+1
(n&1)^1:
当n为奇数:0
当n为偶数:1

#include
using namespace std;
#define ll long long
#define N 100005 
int n;
//小写x,y为曼哈顿距离,大写为切比雪夫距离 
ll sum[2][2],ans,dis,x[N],y[N],X[N],Y[N],_X,_Y;
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int main()
{
    ios::sync_with_stdio(false);	
    cin>>n;
    for(int i=1;i<=n;i++)
    {
     cin>>x[i]>>y[i];
     //原坐标系中的曼哈顿距离==新坐标系中的切比雪夫距离
	 X[i]=x[i]-y[i];
	 Y[i]=x[i]+y[i];	
	} 
	//
	sort(X+1,X+n+1);
	sort(Y+1,Y+n+1); 
	ll a=X[(n+1)/2],b=X[(n+2)/2];
	if(a==b) 
	 sum[0][a&1]=1;
	else
	{
	 sum[0][0]=((b-((b&1)^1))-(a+((a&1)^1)))/2+((b&1)^1)+((a&1)^1);
	 sum[0][1]=((b-(b&1))-(a+(a&1)))/2+(b&1)+(a&1);
	}
	a=Y[(n+1)/2];b=Y[(n+2)/2];
	if(a==b) 
	 sum[1][a&1]=1;
	else
	{
	 sum[1][0]=((b-((b&1)^1))-(a+((a&1)^1)))/2+((b&1)^1)+((a&1)^1);
	 sum[1][1]=((b-(b&1))-(a+(a&1)))/2+(b&1)+(a&1);
	}	
	//
	ans=sum[0][0]*sum[1][0]+sum[0][1]*sum[1][1];
	
	if(ans==0)
	{
		ll DIS=1e18;
		for(int i=0;i<4;i++)
		{
		 _X=X[(n+1)/2]+dir[i][0];
		 _Y=Y[(n+1)/2]+dir[i][1];
		 for(int i=1;i<=n;i++) 
		  dis+=abs(X[i]-_X)+abs(Y[i]-_Y);
		 if (dis 
		 {
		  DIS=dis;ans=1;	
		 }
		 else if(dis==DIS) 
		  ans++;
		 dis=0;			
		}
		cout<<(DIS/2)<<"\n"<;
		return 0;		
	}
	_X=X[(n+1)/2];
	_Y=Y[(n+1)/2];
	if(_X+_Y&1)
	{
	    if(_X(n+2)/2])
	     _X++;
	    else 
		 _Y++;
	}
	for(int i=1;i<=n;i++) 
	 dis+=abs(X[i]-_X)+abs(Y[i]-_Y);
	cout<<(dis/2)<<"\n"<;	 
    return 0;
}

你可能感兴趣的:(2388 首都(曼哈顿距离与切比雪夫距离互转))