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

题目传送门

前置知识:切比雪夫距离和曼哈顿距离的相互转化--自为风月马前卒

有了这个知识,我们便可以在读入松鼠的家的坐标时,先把他转化一下,然后把最后的总式化简,我们会得到一个充满后缀和以及前缀和的式子,这里有十分详细的展开式。于是我们把$x$,$y$坐标分别排序并求出他们的前缀和即可。

之后我们枚举每个点,在这个点意义下求出答案,更新答案最小值。

Code

 1 #include<cstdio>
 2 #include<algorithm>
 3
 4 using namespace std;
 5 typedef long long ll;
 6
 7 int n;
 8 ll tmp,ans=1e16;
 9 ll subx[100090],suby[100090];
10 ll rx[100090],ry[100090];
11 struct node{
12     ll x,y;
13 }p[100090];
14
15 ll check(int u)
16 {
17     int pos=0;
18     ll ax=0,ay=0;
19     pos=lower_bound(rx+1,rx+1+n,p[u].x)-rx;
20     ax+=pos*p[u].x-subx[pos];
21     ax+=subx[n]-subx[pos]-p[u].x*(n-pos);
22     pos=lower_bound(ry+1,ry+1+n,p[u].y)-ry;
23     ay+=pos*p[u].y-suby[pos];
24     ay+=suby[n]-suby[pos]-p[u].y*(n-pos);
25     return ax+ay;
26 }
27
28 int main()
29 {
30     scanf("%d",&n);
31     for(int i=1;i<=n;i++)
32     {
33         ll x=0,y=0;
34         scanf("%lld%lld",&x,&y);
35         rx[i]=x+y;ry[i]=x-y;
36         p[i].x=rx[i],p[i].y=ry[i];
37     }
38     sort(rx+1,rx+1+n);
39     sort(ry+1,ry+1+n);
40     for(int i=1;i<=n;i++)
41         subx[i]=subx[i-1]+rx[i],suby[i]=suby[i-1]+ry[i];
42     for(int i=1;i<=n;i++)
43         tmp=check(i),ans=min(ans,tmp);
44     printf("%lld",ans>>1);
45     return 0;
46 }

* 注意观察式子,在前缀和那里不要用错=w=...

 1 #include<cstdio>
 2 #include<algorithm>
 3
 4 using namespace std;
 5 typedef long long ll;
 6
 7 int n;
 8 ll tmp,ans=1e16;
 9 ll subx[100090],suby[100090];
10 ll rx[100090],ry[100090];
11 struct node{
12     ll x,y;
13 }p[100090];
14
15 ll check(int u)
16 {
17     int pos=0;
18     ll ax=0,ay=0;
19     pos=lower_bound(rx+1,rx+1+n,p[u].x)-rx;
20     ax+=pos*p[u].x-subx[pos];
21     ax+=subx[n]-subx[pos-1]-p[u].x*(n-pos);
22     pos=lower_bound(ry+1,ry+1+n,p[u].y)-ry;
23     ay+=pos*p[u].y-suby[pos];
24     ay+=suby[n]-suby[pos-1]-p[u].y*(n-pos);
25     return ax+ay;
26 }
27
28 int main()
29 {
30     scanf("%d",&n);
31     for(int i=1;i<=n;i++)
32     {
33         ll x=0,y=0;
34         scanf("%lld%lld",&x,&y);
35         rx[i]=x+y;ry[i]=x-y;
36         p[i].x=rx[i],p[i].y=ry[i];
37     }
38     sort(rx+1,rx+1+n);
39     sort(ry+1,ry+1+n);
40     for(int i=1;i<=n;i++)
41         subx[i]=subx[i-1]+rx[i],suby[i]=suby[i-1]+ry[i];
42     for(int i=1;i<=n;i++)
43         tmp=check(i),ans=min(ans,tmp);
44     printf("%lld",ans>>1);
45     return 0;
46 }

WA

原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9770388.html

时间: 2024-10-13 08:27:00

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

BZOJ 3170 TJOI 2013 松鼠聚会 切比雪夫距离

题目大意:给出平面上的一些点,求这些点中的一个使得所有点到这个点的切比雪夫距离之和最短. 思路:切比雪夫距离和曼哈顿距离是可以相互转化的,具体实现就是吧一个点的坐标由(x,y)变成(x - y,x + y),求切比雪夫距离就可以转化成求曼哈顿距离了,很好推. 然后就是暴力枚举每一个点,统计出来每个点的曼哈顿距离之和,最后取一个最小值. CODE: #include <cstdio> #include <cstring> #include <iostream> #incl

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

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,求一遍曼哈顿距离,展开再分类讨论一下发现和上面那

bzoj 3170 Tjoi 2013 松鼠聚会 曼哈顿距离&amp;&amp;切比雪夫距离

因为曼哈顿距离很好求,所以要把每个点的坐标转换一下. 转自:http://blog.csdn.net/slongle_amazing/article/details/50911504 题解 两个点的切比雪夫距离为d=max(|x1?x2|,|y1?y2|)   写一下曼哈顿距离的常用处理方法 两个点(x1,y2),(x2,y2) 其曼哈顿距离=|x1?x2|+|y1?y2| 因为|x1?x2|=max(x1?x2,x2?x1) 所以可以写成=max(x1?x2+y1?y2,x1?x2+y2?y1

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

生命(哈密尔顿距离&amp;切比雪夫距离+前缀和)

数据 题目大意: 已经很简洁了 题解: 对于每个询问,暴力枚举老蛤的位置,\(O(1)\) 统计答案 那么对着原图斜着维护前缀和就行了 或者将曼哈顿距离转换成切比雪夫距离 统计正方形区域前缀和 注意方案中枚举的老蛤的位置要再原图内 AC代码 #include <cstdio> #include <algorithm> using namespace std; const int N=2e3+5; int n,K,Q,s,ans; int a[N][N]; inline int re

曼哈顿距离与切比雪夫距离的亲密♂关系。

先来看一下曼哈顿距离和切比雪夫距离的定义.(以下我可能用\(D_m,D_q\)来表示两者) 曼哈顿距离:\(|x_1-x_2|+|y_1-y_2|\) 切比雪夫距离:\(max(|x_1-x_2|,|y_1-y_2|)\) 至于为什么说他俩关系♂,就是因为他们可以相互转化! 转换关系如下:当坐标为\((x,y)\)时 \(D_m=\)坐标为\((x+y,x-y)\)时的\(D_q\) \(D_q=\)坐标为\((\dfrac{x+y}{2},\dfrac{x-y}{2})\)时的\(D_q\)