你最愿意做的哪件事,才是你的天赋所在

0%

基础计算机和-基础部分2

极坐标

二维平面内,除了根据坐标可以确定一个点之外,通过一个定义好的极角和一个长度也可以确定一个唯一的点。

可以得到

距离

假设$A(x_1,y_1),B(x_2,y_2)$

欧拉距离

欧拉距离就是

欧拉距离计算时需要开放,一般会有误差

曼哈顿距离

切比雪夫距离

曼哈顿距离与切比雪夫距离转换

可以拆开绝对值之后合并得到两个式子

这是式子即为$(x_1+y_2,x_1-y_1),(x_2+y_2,x_2-y_2)$的切比雪夫距离,所以将每一个点(x,y)转化为(x+y,x-y)之后新坐标系得切比雪夫距离即为原坐标系的曼哈顿距离,同理可得(x,y)转化为$(\frac{x+y}{2},\frac{x-y}{2})$,转化后的曼哈顿距离即为切比雪夫距离

例题

洛谷P3964-切比雪夫转曼哈顿

思路

首先知道题目要我们求的是找到一点,使得其他点到这题的切比雪夫距离最短。我们把坐标转化为曼哈顿距离得到距离公式

然后我们假设现在坐标有序,就可以得到一个前缀和的式子,但是我们现在不知道我们的点前面有多少个比x小,有多少个比y小,所以我们考虑把点映射到一个数组上,例如p(2,3)找到这个点在x数组中的位置,找到y中的位置,我们只需要对x,y数组进行排序,就可以得到前面有多少个是负的,多少个是正的,这样就可以使用前缀和来统计答案了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5+10;
const ll inf = 0x3f3f3f3f3f3f3f3f;
struct node
{
ll x,y;
int xid,yid;
}p[N];
struct local
{
ll num;
int id;
bool operator < (const local a)
{
return num<a.num;
}
}x[N],y[N];
ll prex[N],prey[N];
int n;
void trans()
{
for(int i=1;i<=n;i++)
{
int xx=p[i].x;
int yy=p[i].y;
p[i].x=xx+yy;
p[i].y=xx-yy;
x[i].num=p[i].x;
y[i].num=p[i].y;
x[i].id=i;
y[i].id=i;
}
sort(x+1,x+n+1);
sort(y+1,y+n+1);
prex[0]=0;
prey[0]=0;
for(int i=1;i<=n;i++)
{
p[x[i].id].xid=i;
p[y[i].id].yid=i;
prex[i]=prex[i-1]+x[i].num;
prey[i]=prey[i-1]+y[i].num;
}
ll ans = inf;
for(int i=1;i<=n;i++)
{
int xid = p[i].xid;
int yid = p[i].yid;
ans=min(xid*p[i].x-prex[xid]+(prex[n]-prex[xid])-(n-xid)*p[i].x+
yid*p[i].y-prey[yid]+prey[n]-prey[yid]-(n-yid)*p[i].y,ans);
}
printf("%lld\n",ans>>1);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld %lld",&p[i].x,&p[i].y);
}
trans();
}

-------------你最愿意做的哪件事才是你的天赋所在-------------