一般的なアイデア
直交座標系でnnを与えるnドット(n≤2・1 0 5)(n \ le 2 \ cdot 10 ^ 5)(n≤2⋅1 05)、2点間の最大のマンハッタン距離が必要です
問題解決のアイデア
まず、各点(x、y)(x、y)を列挙します。(x 、y )そして残りの各点(u、v)(u、v)を置く(u 、v ) 4つのカテゴリに分類
- で(x、y)は(x、y)は(x 、y )は、ソースポイントの参照フレームの第1象限です。
- で(x、y)は(x、y)は(x 、y )は、ソースポイントの参照フレームの第2象限です。
- で(x、y)は(x、y)は(x 、y )は、ソースポイントの参照フレームの第3象限です。
- で(x、y)は(x、y)は(x 、y )は、ソースポイントの参照フレームの第4象限です。
ここで、いくつかの象限に含まれる座標軸を読み返してみると、これは
後で以 (x,y) 为源点的参考系
「参考系
次へ」と呼ばれる計算式の結果に影響を与えないことがわかります。計算式は、マンハッタン距離をリストします。
- 第1象限:− x − y + u + v -x-y + u + v− x−Y+u+v
- 第2象限:x − y − u + v xy-u + vバツ−Y−u+v
- 第3象限:x + y − u − v x + yuvバツ+Y−u−v
- 第4象限:− x + y + u − v -x + y + uv− x+Y+u−v
参照フレームの各象限の各ポイント(u、v)(u、v)(u 、v )、それらは(x、y)(x、y)と同じです(x 、y )はマンハッタン距離にx、yx、yを含みますx 、y部分は既知です。したがって、u、vu、vを最大化するだけで済みますu 、vの一部。
四つの異なる計算式があるので、我々は、各ポイントを置く4 4初めに4つの異なる配列は、各象限の計算式に従ってソートされます。
最後に、各点を列挙するとき、4つの配列u、vu、vu 、パートvで最大の点のマンハッタン距離を見つけ、答えを更新します
各コンテナのu、vu、vに注意してくださいu 、vパーツの最大のポイント(コンテナの上部のポイントと呼びます)は、必ずしもコンテナの対応する象限に属しているとは限りませんが
、この方法は正しいです。なぜなら、特定のコンテナがaa象限に対応する容器、対応する容器象限の上部に属さない点BBbによって生成される答えは、コンテナaa以上である必要があります生成された答え。なぜならああ一番上のポイントは、参加しなければならBBbの答えの計算
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
int n;
long long ans;
struct node{
int x,y;
node(int u,int v)
{
x=u,y=v;
}
};
vector <node> c[4];
inline bool cmp1(node x,node y)
{
return x.x+x.y > y.x+y.y;
}
inline bool cmp2(node x,node y)
{
return -x.x+x.y > -y.x+y.y;
}
inline bool cmp3(node x,node y)
{
return -x.x-x.y > -y.x-y.y;
}
inline bool cmp4(node x,node y)
{
return x.x-x.y > y.x-y.y;
}
inline int read()
{
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;ch=getchar();}
while(ch>='0' && ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return s*w;
}
int main()
{
n=read();
int u,v;
for(int i=1;i<=n;++i)
{
int x=read(),y=read();
c[0].push_back(node(x,y));
c[1].push_back(node(x,y));
c[2].push_back(node(x,y));
c[3].push_back(node(x,y));
}
sort(c[0].begin(),c[0].end(),cmp1);
sort(c[1].begin(),c[1].end(),cmp2);
sort(c[2].begin(),c[2].end(),cmp3);
sort(c[3].begin(),c[3].end(),cmp4);
for(int i=0;i<n;++i)
{
int x=c[0][i].x,y=c[0][i].y;
for(int j=0;j<4;++j)
{
u=c[j][0].x,v=c[j][0].y;
ans=max(ans,(long long)abs(x-u)+abs(y-v));
// 注意这里一定要用曼哈顿距离的通用计算式
}
}
printf("%lld\n",ans);
return 0;
}