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<cstring>

#include<algorithm>

using namespace std;

#define X(o) x[rx[o]]

#define Y(o) y[ry[o]]

typedef long long ll;

const int maxn = 100009;

ll smx[maxn], smy[maxn], ans;

int N, x[maxn], y[maxn], rx[maxn], ry[maxn];

bool cmpX(const int &l, const int &r) {

return x[l] < x[r];

}

bool cmpY(const int &l, const int &r) {

return y[l] < y[r];

}

int BS(int c[], int r[], int v) {

int L = 0, R = N - 1;

while(L <= R) {

int m = (L + R) >> 1;

if(c[r[m]] == v)

return m;

c[r[m]] < v ? L = m + 1 : R = m - 1;

}

return -1;

}

int main() {

scanf("%d", &N);

for(int i = 0; i < N; i++) {

rx[i] = ry[i] = i;

int _x, _y;

scanf("%d%d", &_x, &_y);

x[i] = _x + _y;

y[i] = _x - _y;

}

sort(rx, rx + N, cmpX);

sort(ry, ry + N, cmpY);

smx[0] = X(0);

smy[0] = Y(0);

for(int i = 1; i < N; i++) {

smx[i] = smx[i - 1] + X(i);

smy[i] = smy[i - 1] + Y(i);

}

ans = 1LL << 60;

for(int i = 0; i < N; i++) {

int px = BS(x, rx, x[i]), py = BS(y, ry, y[i]);

ll t = 0;

if(!px) {

t += smx[N - 1] - ll(N) * x[i];

} else {

t += ll(x[i]) * (px * 2 + 2 - N) - 2LL * smx[px] + smx[N - 1];

}

if(!py) {

t += smy[N - 1] - ll(N) * y[i];

} else {

t += ll(y[i]) * (py * 2 + 2 - N) - 2LL * smy[py] + smy[N - 1];

}

ans = min(t, ans);

}

printf("%lld\n", ans >> 1);

return 0;

}

-------------------------------------------------------------------------

3170: [Tjoi 2013]松鼠聚会

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 874  Solved: 421
[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

时间: 2024-12-20 18:56:07

BZOJ 3170: [Tjoi 2013]松鼠聚会( sort )的相关文章

BZOJ 3170 [Tjoi 2013]松鼠聚会

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

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

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

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

BZOJ 3170 Tjoi 2013 松鼠聚会 计算几何

题目大意:给定平面上的n个点,求这n个点中的一个点到这n个点的切比雪夫距离之和最小 切比雪夫距离,即各坐标差绝对值的最大值 首先我们如果想把曼哈顿距离转化成切比雪夫距离 那么就要把点(x,y)变成(x+y,x-y) 这样新点之间的切比雪夫距离就是原点之间的曼哈顿距离 同理,我们可以把切比雪夫距离转化成曼哈顿距离 即把点(x,y)变成((x+y)/2,(x-y)/2) 然后将横纵坐标排序 维护前缀和 分开讨论横纵坐标的曼哈顿距离即可 避免double,最后算出距离再除以2 #include <cm

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^

3170: [Tjoi 2013]松鼠聚会

3170: [Tjoi 2013]松鼠聚会 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

【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

bzoj3170 [Tjoi 2013]松鼠聚会

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 表示为了聚会走的路程和最小为多少. 首先等价变换,旋转坐标系45度,将点(x,y)改为((x+y)/2,(x-y)/

BZOJ 3171 TJOI 2013 循环格 费用流

题目大意:给出一个表格,每个表格指向周围四个格子中的一个,问你可以改变一些格子上的指向,问让所有格子都在圈中最小需要改变多少. 思路:所有的格子都在圈中,由于每个格子只能有一个出边,所以就要保证所有格子都有一个入边.建立费用流的模型,所有点向汇点连流量1费用0的边,表示要接受一个入边.S向所有点连一条流量1费用0的边,表示一条出边.一个格子向周围四个格子连边,流量1,如果方向与当前方向相符,那么费用0,否则费用1.之后跑费用流就是答案了. CODE: #include <queue> #inc