hdu 4311 & 4312 Meeting point 曼哈顿距离之和最小
hdu 4311
题意
平面上\(n(n\leq 1e5)\)个点,找一个点到其它所有点的曼哈顿距离之和最小。
思路
如果是找一个坐标使得所有点到其曼哈顿距离之和最小,那么将\(n\)个横坐标排个序,取中间的一个为答案的横坐标,将\(n\)个纵坐标排个序,取中间的一个为答案的纵坐标。原因就是绝对值$$y=|x-a_1|+|x-a_2|+...+|x-a_n|$$的图像为平底锅型或者是尖底。因为可以在平面上任意取点,所以可以取最优的\(x\)和\(y\).
但是这道题并不能够任意取点,而是限定在了\(n\)个点中。怎么办呢?
最常规的想法,就是将距离都算出来,取个最小值。然而直接算的话是\(O(n^2)\)的,数据量显然不允许。那么就换种算的方法。
还是先排序,考虑序列\(a_1,a_2,...,a_n\)(已升序排好),则$$|a_i-a_1|+|a_i-a_2|+...+|a_i-a_{i-1}|+|a_i-a_{i+1}|+...+|a_i-a_n|$$$$=((a_i-a_1)+(a_i-a_2)+...+(a_i-a_{i-1}))+((a_{i+1}-a_i)+...+(a_n-a_i))$$$$=(i-1)a_i-\sum_{k=1}{i-1}a_k-(n-i)*a_i+\sum_{k=i+1}{n}a_k$$$$=(2i-1-n)*a_i-\sum_{k=1}{i-1}a_k+\sum_{k=i+1}{n}a_k$$
于是可以预处理前缀和后缀和,就可以在\(O(n)\)的时间处理出来各个点对应的值了。
最后每个点的横坐标距离和纵坐标距离加起来取个最小值即可。
算法复杂度\(O(nlogn)\).
Code
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f3f3f3f3f
#define maxn 100010
using namespace std;
typedef long long LL;
struct node {
LL x, y;
}a[maxn];
bool cmp1(int i, int j) { return a[i].x < a[j].x; }
bool cmp2(int i, int j) { return a[i].y < a[j].y; }
LL x[maxn], y[maxn], pr[maxn], su[maxn];
int id[maxn];
void work() {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; ++i) scanf("%lld%lld", &a[i].x, &a[i].y);
for (int i = 1; i <= n; ++i) id[i] = i;
sort(id+1, id+1+n, cmp1);
memset(pr, 0, sizeof pr);
memset(su, 0, sizeof su);
for (int i = 1; i <= n; ++i) pr[i] = pr[i-1] + a[id[i]].x;
su[n] = a[id[n]].x; for (int i = n-1; i > 0; --i) su[i] = su[i+1] + a[id[i]].x;
for (int i = 1; i <= n; ++i) x[id[i]] = (2*i-1-n)*a[id[i]].x - pr[i-1] + su[i+1];
sort(id+1, id+1+n, cmp2);
memset(pr, 0, sizeof pr);
memset(su, 0, sizeof su);
for (int i = 1; i <= n; ++i) pr[i] = pr[i-1] + a[id[i]].y;
su[n] = a[id[n]].y; for (int i = n-1; i > 0; --i) su[i] = su[i+1] + a[id[i]].y;
for (int i = 1; i <= n; ++i) y[id[i]] = (2*i-1-n)*a[id[i]].y - pr[i-1] + su[i+1];
LL ans = inf;
for (int i = 1; i <= n; ++i) ans = min(ans, x[i]+y[i]);
printf("%lld\n", ans);
}
int main() {
int T;
scanf("%d", &T);
while (T--) work();
return 0;
}
hdu 4312
题意
平面上\(n(n\leq 1e5)\)个点,找一个点到其它所有点的切比雪夫距离之和最小。
思路
将切比雪夫距离转化为曼哈顿距离,方法为将坐标转45度。即将\((x,y)\)的坐标映射为\((x+y,y-x)\).
然后就可以直接套上一题了,最终答案除以2.
Code
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f3f3f3f3f
#define maxn 100010
using namespace std;
typedef long long LL;
struct node {
LL x, y;
}a[maxn];
bool cmp1(int i, int j) { return a[i].x < a[j].x; }
bool cmp2(int i, int j) { return a[i].y < a[j].y; }
LL x[maxn], y[maxn], pr[maxn], su[maxn];
int id[maxn];
void work() {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
LL xx, yy;
scanf("%lld%lld", &xx, &yy);
a[i].x = xx+yy, a[i].y = yy-xx;
}
for (int i = 1; i <= n; ++i) id[i] = i;
sort(id+1, id+1+n, cmp1);
memset(pr, 0, sizeof pr);
memset(su, 0, sizeof su);
for (int i = 1; i <= n; ++i) pr[i] = pr[i-1] + a[id[i]].x;
su[n] = a[id[n]].x; for (int i = n-1; i > 0; --i) su[i] = su[i+1] + a[id[i]].x;
for (int i = 1; i <= n; ++i) x[id[i]] = (2*i-1-n)*a[id[i]].x - pr[i-1] + su[i+1];
sort(id+1, id+1+n, cmp2);
memset(pr, 0, sizeof pr);
memset(su, 0, sizeof su);
for (int i = 1; i <= n; ++i) pr[i] = pr[i-1] + a[id[i]].y;
su[n] = a[id[n]].y; for (int i = n-1; i > 0; --i) su[i] = su[i+1] + a[id[i]].y;
for (int i = 1; i <= n; ++i) y[id[i]] = (2*i-1-n)*a[id[i]].y - pr[i-1] + su[i+1];
LL ans = inf;
for (int i = 1; i <= n; ++i) ans = min(ans, x[i]+y[i]);
printf("%lld\n", ans/2);
}
int main() {
int T;
scanf("%d", &T);
while (T--) work();
return 0;
}
hdu 4311 & 4312 Meeting point 曼哈顿距离之和最小的更多相关文章
- Hdu4311 || 4312Meeting point-1/-2 n个点中任意选一个点使得其余点到该点曼哈顿距离之和最小
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...
- 某个点到其他点的曼哈顿距离之和最小(HDU4311)
Meeting point-1 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- 【HDU 4311】Meeting point-1(前缀和求曼哈顿距离和)
题目链接 正经解法: 给定n个点的坐标,找一个点,到其他点的曼哈顿距离之和最小.n可以是100000.大概要一个O(nlogn)的算法.算曼哈顿距离可以把x和y分开计算排好序后计算前缀和就可以在O(1 ...
- 51Nod 1108 距离之和最小 V2 1096 距离之和最小 中位数性质
1108 距离之和最小 V2基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注三维空间上有N个点, 求一个点使它到这N个点的曼哈顿距离之和最小,输出这个最小 ...
- HDU 4311 Meeting point-1 求一个点到其它点的曼哈顿距离之和
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4311 解题报告:在一个平面上有 n 个点,求一个点到其它的 n 个点的距离之和最小是多少. 首先不得不 ...
- 51nod 1096 距离之和最小 1108 距离之和最小 V2
[题解] 很显然在一条坐标轴上到各个点距离之和最小的点就是它们的中位数.怎么证明呢?我们假设现在找的某个点x左边有a个点,右边有b个点(a>b).我们把x向左移动d个单位,并保证x左边依然有a个 ...
- 51Nod 1110 距离之和最小 V3 中位数 思维
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 X轴上有N个点,每个点除了包括一个位置数据X[i],还包括一个权值W[i].点P到点P[i]的带权距离 = 实际距离 ...
- 51nod1110 距离之和最小 V3
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 X轴上有N个点,每个点除了包括一个位置数据X[i],还包括一个权值W[i].该点到其他点的带权距离 = 实际距离 * 权值.求X轴上 ...
- 【51NOD】1096 距离之和最小
[算法]数学 [题解] 其实就是求中位数,奇数个点就是最中间的点,偶数个点就是最中间两个点和它们之间的区域皆可(所以偶数不必取到两点正中央,取两点任意一点即可). 我们可以想象现在x轴上有n个点,我们 ...
随机推荐
- Linux运维笔记--第三部
第三部 3. Linux系统文件重要知识初步讲解 # ls -lhi (i: inode,每个文件前的数字代表文件身份ID:h: human 人类可读) 显示:25091 -rw-r--r-- ...
- 头文件string与string.h的区别
在C++中,#include<iostream>与#include<iostream.h>的区别,前者要使用更新的编译器(其实大部分编译器多比较前卫了,出了有些搞嵌入式的用变态 ...
- k8s的高级调度方式
默认的scheduler的调度过程:1.预选策略:从所有节点当中选择基本符合选择条件的节点.2.优选函数:在众多符合基本条件的节点中使用优选函数,计算节点各自的得分,通过比较进行排序.3.从最高得分的 ...
- 02Vs2013常用路径配置
1.设置头文件路径 项目 -> xxx属性页 -> 配置属性 -> C/C++ -> 常规 -> 附加包含目录. 2.包含 x.lib 库路径 项目 -> xxx属 ...
- windows server 服务器 环境配置
自动备份 xcopy d:\web\zhiku\*.* d:\bak\web\zhiku\%date:~,4%%date:~5,2%%date:~8,2%\ /S /I
- 【laravel】Disabling CSRF for Specific Routes - Laravel 5
原文 http://www.camroncade.com/disable-csrf-for-specific-routes-laravel-5/ Disabling CSRF for Specific ...
- makedown语法
文章转载至:https://blog.csdn.net/u014061630/article/details/81359144#1-%E5%BF%AB%E6%8D%B7%E9%94%AE 前言 写过博 ...
- OverflowError:django signed integer is greater than maximum
在学习一对一查询的时候,打印作者的电话时报了这个错 alex = Author.objects.filter(name='alex').first() print(alex.authordetail. ...
- Letters CodeForces - 978C (二分)
Time limit4000 ms Memory limit262144 kB There are nn dormitories in Berland State University, they a ...
- Nordic Collegiate Programming Contest 2015 B. Bell Ringing
Method ringing is used to ring bells in churches, particularly in England. Suppose there are 6 bells ...