【bzoj3170】[Tjoi2013]松鼠聚会

3170: [Tjoi2013]松鼠聚会

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit:
1670  Solved: 885
[Submit][Status][Discuss]

Description

有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点,距离为1。现在N个松鼠要走到一个松鼠家去,求走过的最短距离。

Input

第一行给出数字N,表示有多少只小松鼠。0<=N<=10^5
下面N行,每行给出x,y表示其家的坐标。
-10^9<=x,y<=10^9

Output

表示为了聚会走的路程和最小为多少。

Sample Input

6
-4 -1
-1 -2
2
-4
0 2
0 3
5 -2

Sample Output

20

HINT

Source

[Submit][Status][Discuss]

题意:N个点,求某一个点到其他点的切比雪夫距离之和最小化;

题解:

推荐一篇页面比较好讲得很清楚的博客:https://www.cnblogs.com/zwfymqz/p/8253530.html

两个点(x1,y1) 和 (x2,y2)

切比雪夫距离:max(|x1-x2|,|y1-y2|)

曼哈顿距离:|x1-x2|+|y1-y2|

先介绍绝对值的两个性质:|a|+|b| = max(|a+b|,|a-b|)  max(|a|,|b|) = |(a+b)/2|+|(a-b)/2|

可以利用数轴理解一下;

利用上面的性质可以知道:
        若:(x,y) – > (x-y,x+y) 则新图的切比雪夫距离为原图的曼哈顿距离;

若:(x,y) – > ((x-y)/2,(x+y)/2) 则新图的曼哈顿距离为原图的切比雪夫距离;

为什么要转化呢?

切比雪夫不好处理,转化后对曼哈顿距离分x,y排序,预处理某个值到前面的曼哈顿距离之和,可以做到O(1)查询,此题直接枚举哪个点;

另外如果最近的点不要求在这些点里面而是平面的任何一个点,分别贪心选取x坐标,y坐标的排序后的中位数,注意切比雪夫转曼哈顿,有可能不是整点,要求整点还需要特判一下;

 1
 2 #include<cstdio>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<queue>
 7 #include<cmath>
 8 #include<vector>
 9 #include<stack>
10 #include<map>
11 #define Run(i,l,r) for(int i=l;i<=r;i++)
12 #define Don(i,l,r) for(int i=l;i>=r;i--)
13 #define ll long long
14 #define inf 0x3f3f3f3f
15 using namespace std;
16 const int N=100010;
17 int n,px[N],py[N];
18 ll upx[N],dnx[N],upy[N],dny[N];
19 struct data{
20     int x,id;
21     bool operator <(const data&A)const{
22         return x<A.x;
23     }
24 }X[N],Y[N];
25 int main(){
26 //  freopen("bzoj3170.in","r",stdin);
27 //  freopen("bzoj3170.out","w",stdout);
28     scanf("%d",&n);
29     for(int i=1;i<=n;i++){
30         int a,b;
31         scanf("%d%d",&a,&b);
32         X[i]=(data){a-b,i};
33         Y[i]=(data){a+b,i};
34     }
35     sort(X+1,X+n+1);
36     sort(Y+1,Y+n+1);
37     for(int i=1;i<=n;i++){
38         px[X[i].id]=i;
39         py[Y[i].id]=i;
40     }
41     ll ans=1e18;
42     for(int i=1;i<=n;i++){
43         upx[i]=upx[i-1]+1ll*(i-1)*(X[i].x-X[i-1].x);
44         upy[i]=upy[i-1]+1ll*(i-1)*(Y[i].x-Y[i-1].x);
45     }
46     for(int i=n;i;i--){
47         dnx[i]=dnx[i+1]+1ll*(n-i)*(X[i+1].x-X[i].x);
48         dny[i]=dny[i+1]+1ll*(n-i)*(Y[i+1].x-Y[i].x);
49     }
50     for(int i=1;i<=n;i++){
51         ans=min(ans,upx[px[i]]+dnx[px[i]]+upy[py[i]]+dny[py[i]]);
52     }
53     printf("%lld\n",ans>>1);
54     return 0;
55 }//by tkys_Austin;

原文地址:https://www.cnblogs.com/Paul-Guderian/p/9814343.html

时间: 2024-12-09 11:44:21

【bzoj3170】[Tjoi2013]松鼠聚会的相关文章

P3964 [TJOI2013]松鼠聚会

题目描述 草原上住着一群小松鼠,每个小松鼠都有一个家.时间长了,大家觉得应该聚一聚.但是草原非常大,松鼠们都很头疼应该在谁家聚会才最合理. 每个小松鼠的家可以用一个点x,y表示,两个点的距离定义为点(x,y)和它周围的8个点(x-1,y)(x+1,y),(x,y-1),(x,y+1).(x-1,y+1),(x-1,y-1),(x+1,y+1),(x+1,y-1)距离为1. 输入输出格式 输入格式: 第一行是一个整数N,表示有多少只松鼠.接下来N行,第i行是两个整数x和y,表示松鼠i的家的坐标 输

[Tjoi2013]松鼠聚会

Description 有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点,距离为1.现在N个松鼠要走到一个松鼠家去,求走过的最短距离. Input 第一行给出数字N,表示有多少只小松鼠.0<=N<=10^5 下面N行,每行给出x,y表示其家的坐标. -10^9<=x,y<=10^9 Output 表示为了聚会走的路程和最小为多少. Sample Input 6 -4 -1 -1 -2 2 -4 0 2 0 3

BZOJ_3170_[Tjoi2013]松鼠聚会_切比雪夫距离+前缀和

题意:有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点,距离为1.现在N个松鼠要走到一个松鼠家去,求走过的最短距离. 分析: 这啥奇怪的距离表示啊.推了一下发现是max{ abs(x[i] - x[j]),abs(y[i] - y[j] }.然后就不会了. 看题姐:这个东西叫切比雪夫距离,可以和曼哈顿距离转化. 把坐标变成(x[i]-y[i])/2,(x[i]+y[i])/2,求一遍曼哈顿距离,展开再分类讨论一下发现和上面那

LuoguP3964 [TJOI2013]松鼠聚会【切比雪夫距离/前缀和】

题目传送门 前置知识:切比雪夫距离和曼哈顿距离的相互转化--自为风月马前卒 有了这个知识,我们便可以在读入松鼠的家的坐标时,先把他转化一下,然后把最后的总式化简,我们会得到一个充满后缀和以及前缀和的式子,这里有十分详细的展开式.于是我们把$x$,$y$坐标分别排序并求出他们的前缀和即可. 之后我们枚举每个点,在这个点意义下求出答案,更新答案最小值. Code 1 #include<cstdio> 2 #include<algorithm> 3 4 using namespace s

luoguP3964 [TJOI2013]松鼠聚会

链接 luogu 思路 切比雪夫距离有max,不好优化. 但是我们能转化成曼哈顿距离,只需要 \((x,y)变成(\frac{x+y}{2},\frac{x-y}{2})\) 相反的曼哈顿距离转切比雪夫距离 \((x,y)=>(x+y,x-y)\) 详情见attack 剩下的就是sort直接做了 代码 #include <bits/stdc++.h> #define ll long long using namespace std; const int N=1e5+7; int n; s

bzoj3170【TJOI2013】松鼠聚会

3170: [Tjoi 2013]松鼠聚会 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 965  Solved: 475 [Submit][Status][Discuss] Description 有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点,距离为1.现在N个松鼠要走到一个松鼠家去,求走过的最短距离. Input 第一行给出数字N,表示有多少只小松鼠.0<=N<=

【BZOJ3170】[Tjoi 2013]松鼠聚会 旋转坐标系

[BZOJ3170][Tjoi 2013]松鼠聚会 有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点,距离为1.现在N个松鼠要走到一个松鼠家去,求走过的最短距离. Input 第一行给出数字N,表示有多少只小松鼠.0<=N<=10^5下面N行,每行给出x,y表示其家的坐标.-10^9<=x,y<=10^9 Output 表示为了聚会走的路程和最小为多少. Sample Input 6 -4 -1 -1 -2 2

bzoj-3170 3170: [Tjoi 2013]松鼠聚会(计算几何)

题目链接: 3170: [Tjoi 2013]松鼠聚会 Time Limit: 10 Sec  Memory Limit: 128 MB Description 有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点,距离为1.现在N个松鼠要走到一个松鼠家去,求走过的最短距离. Input 第一行给出数字N,表示有多少只小松鼠.0<=N<=10^5下面N行,每行给出x,y表示其家的坐标.-10^9<=x,y<=10^

BZOJ 3170: [Tjoi 2013]松鼠聚会( sort )

题目的距离为max(|x1-x2|, |y1-y2|) (切比雪夫距离). 切比雪夫距离(x, y)->曼哈顿距离((x+y)/2, (x-y)/2) (曼哈顿(x, y)->切比雪夫(x+y, x-y)). 转成Manhattan distance后排序前缀和维护即可. -------------------------------------------------------------------------- #include<cstdio> #include<cs