https://www.luogu.com.cn/problem/AT_abc351_e
*这是我的第一个随笔,请大佬们指正。
- 数学知识:https://oi-wiki.org/geometry/distance/
*曼哈顿距离:在二维空间内,两个点之间的曼哈顿距离(Manhattan distance)为它们横坐标之差的绝对值与纵坐标之差的绝对值之和。设点 A(x1,y1),B(x2,y2),则 A,B 之间的曼哈顿距离用公式可以表示为:d(A,B)=|x1-x2|+|y1-y2|。
*切比雪夫距离:在二维空间内,两个点之间的切比雪夫距离为它们横坐标之差的绝对值与纵坐标之差的绝对值的最大值。设点 A(x1,y1),B(x2,y2),则 A,B 之间的切比雪夫距离用公式可以表示为:d(A,B)=max(|x1-x2|, |y1-y2|)。 - 题目大意:
- 解题思路:
这只兔子是斜着走的,所以它斜着走一步步数加1,也就相当于从两点之间的距离就是切比雪距离max(|x1-x2|, |y1-y2|),这里我们可以通过将曼哈顿距离转换为切比雪距离:
证明如下:
假设 A(x1,y1),B(x2,y2),我们把曼哈顿距离中的绝对值拆开,能够得到四个值,这四个值中的最大值是两个非负数之和,即曼哈顿距离。则 A,B 两点的曼哈顿距离为:
\begin{aligned}
d(A,B)&=|x1-x2|+|y1-y2|=\max\begin{Bmatrix}x1-x2+ y1-y2,x1-x2+y2-y1,x2-x1+y1-y2,x2-x1+y2-y1\end{Bmatrix}\
&= \max(|(x1+y1)-(x2+y2)|,|(x1-y1)-(x2-y2)|)
\end{aligned}
我们很容易发现,这就是 (x1+y1,x1-y1), (x2+y2,x2-y2) 两点之间的切比雪夫距离。所以将每一个点 (x,y) 转化为 (x+y,x-y),新坐标系下的切比雪夫距离即为原坐标系下的曼哈顿距离。
我们可以通过将坐标系转个45度来实现正常的上下左右,这里还可以发现题目要分奇偶,分段相加。
具体代码如下:
点击查看代码
#include<bits/stdc++.h>
#define ok ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define fo(i,x,y) for(int i=x;i<=y;i++)
#define sd(a) cin>>a
#define sdd(a,b) cin>>a>>b
#define sddd(a,b,c) cin>>a>>b>>c
#define st(a) cout<<a<<endl
#define int long long
using namespace std;
const int N=200010;
int x[N],y[N],nowx[N],nowy[N];
int ans,n,cnt,sum;
void solve(){
sort(nowx+1,nowx+1+cnt);
sort(nowy+1,nowy+1+cnt);
for(int i=1,sum=0;i<=cnt;i++)ans+=nowx[i]*(i-1)-sum,sum+=nowx[i];
for(int i=1,sum=0;i<=cnt;i++)ans+=nowy[i]*(i-1)-sum,sum+=nowy[i];
}
signed main(){
ok;
sd(n);
fo(i,1,n)sdd(x[i],y[i]);
fo(i,1,n){
if((x[i]+y[i])&1)nowx[++cnt]=x[i]+y[i],nowy[cnt]=x[i]-y[i];
}
solve();
cnt=0;
fo(i,1,n){
if(!((x[i]+y[i])&1))nowx[++cnt]=x[i]+y[i],nowy[cnt]=x[i]-y[i];
}
solve();
st(ans/2);
return 0;
}