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个点,我们 ...
随机推荐
- 01_3_创建一个Action
01_3_创建一个Action 1. 定义一个action 具体视图的返回可以由用户自己定义的Action来决定 具体的手段是根据返回的字符串找到相应的配置项,来决定视图的内容 具体Action的实现 ...
- iOS开发-动画总结
一.简介 IOS 动画主要是指Core Animation框架.官方使用文档地址为:Core Animation Guide.Core Animation是IOS和OS X平台上负责图形渲染与动画的基 ...
- javascript设计模式(张容铭)学习笔记 - 外观模式绑定事件
有一个需求要为document对象绑定click事件来是想隐藏提示框的交互功能,于是小白写了如下代码: document.onclick = function(e) { e.preventDefaul ...
- CF-1143D. The Beatles
题意:有间隔为k的n个点在数轴上,下标为 \(1,k+1, 2*k+1,\cdots (n-1)*k+1\) 首尾相接.设起点为s,步长为L,而现在只知道s距离最近的点的距离为a,和(s+L)距离最近 ...
- Java 的Throwable、error、exception的区别
1. 什么是异常? 异常本质上是程序上的错误,包括程序逻辑错误和系统错误.比如使用空的引用(NullPointerException).数组下标越界(IndexOutOfBoundsException ...
- Git - revert详解
git revert 撤销 某次操作,此次操作之前和之后的commit和history都会保留,并且把这次撤销作为一次最新的提交 * git revert HEAD ...
- CentOS 7.4 基于LNMP搭建wordpress
之前有好多次搭建wordpress的经历,有在Ubuntu系统上,有在CentOS7.2系统上,但都是搭完还是稀里糊涂的,因为好多都是教程上照着敲的.这次好好出个教程,以便以后方便查看. 准备工作:C ...
- windows charles 抓包https请求
charles证书 2.设置host和端口 3.浏览器访问即可抓到https的请求
- 如何用纯 CSS 创作一个过山车 loader
效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/KBxYZg/ 可交互视频 此视频是 ...
- ise与win8兼容解决方案
win8中ise无法加载code,显示impact4.exe停止运行. 解决方法如下: 找到程序安装路径 1.进入文件夹 D:\Xilinx\14.6\ISE_DS\ISE\lib\nt64 把li ...