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 曼哈顿距离之和最小的更多相关文章

  1. Hdu4311 || 4312Meeting point-1/-2 n个点中任意选一个点使得其余点到该点曼哈顿距离之和最小

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...

  2. 某个点到其他点的曼哈顿距离之和最小(HDU4311)

    Meeting point-1 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  3. 【HDU 4311】Meeting point-1(前缀和求曼哈顿距离和)

    题目链接 正经解法: 给定n个点的坐标,找一个点,到其他点的曼哈顿距离之和最小.n可以是100000.大概要一个O(nlogn)的算法.算曼哈顿距离可以把x和y分开计算排好序后计算前缀和就可以在O(1 ...

  4. 51Nod 1108 距离之和最小 V2 1096 距离之和最小 中位数性质

    1108 距离之和最小 V2基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注三维空间上有N个点, 求一个点使它到这N个点的曼哈顿距离之和最小,输出这个最小 ...

  5. HDU 4311 Meeting point-1 求一个点到其它点的曼哈顿距离之和

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4311 解题报告:在一个平面上有 n 个点,求一个点到其它的 n 个点的距离之和最小是多少. 首先不得不 ...

  6. 51nod 1096 距离之和最小 1108 距离之和最小 V2

    [题解] 很显然在一条坐标轴上到各个点距离之和最小的点就是它们的中位数.怎么证明呢?我们假设现在找的某个点x左边有a个点,右边有b个点(a>b).我们把x向左移动d个单位,并保证x左边依然有a个 ...

  7. 51Nod 1110 距离之和最小 V3 中位数 思维

    基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 X轴上有N个点,每个点除了包括一个位置数据X[i],还包括一个权值W[i].点P到点P[i]的带权距离 = 实际距离 ...

  8. 51nod1110 距离之和最小 V3

    基准时间限制:1 秒 空间限制:131072 KB 分值: 40  X轴上有N个点,每个点除了包括一个位置数据X[i],还包括一个权值W[i].该点到其他点的带权距离 = 实际距离 * 权值.求X轴上 ...

  9. 【51NOD】1096 距离之和最小

    [算法]数学 [题解] 其实就是求中位数,奇数个点就是最中间的点,偶数个点就是最中间两个点和它们之间的区域皆可(所以偶数不必取到两点正中央,取两点任意一点即可). 我们可以想象现在x轴上有n个点,我们 ...

随机推荐

  1. Flash as3.0 保存MovieClip运动轨迹到json文件

    //放在第一帧调用 import flash.events.Event; import flash.display.MovieClip; stage.addEventListener(Event.EN ...

  2. SEO 优化

    1.什么是SEO优化: 简单的来说就是了解搜索引擎的排名规则,投机所好,让我们的网站在搜索引擎上得到靠前的排名,获取更多流量的一种方式. 2.SEO优化-衡量标准 关键词的排名--核心关键词的效果 收 ...

  3. python2与python3的bytes问题

    >>> s = '编程' >>> print s 编程 >>> s '\xe7\xbc\x96\xe7\xa8\x8b' >>> ...

  4. 在spring boot中使用webSocket组件(二)

    该篇演示如何使用websocket创建一对一的聊天室,废话不多说,我们马上开始! 一.首先先创建前端页面,代码如下图所示: 1.login.html <!DOCTYPE html> < ...

  5. HDU 5237 Base64 模拟

    题意: 输入一个明文串,输出\(k\)次\(Base64\)加密以后得到的串. 分析: 好像没什么Trick,直接模拟就行了. 注意:长度为\(3k+1\)的串,后面会有两个\(=\).长度为\(3k ...

  6. JAVA-基础(六) Java.serialization 序列化

    序 列 化 序列化(serialization)是把一个对象的状态写入一个字节流的过程. Serializable接口 只有一个实现Serializable接口的对象可以被序列化工具存储和恢复.Ser ...

  7. Jquery+Ajax+asp.net+sqlserver-编写的通用邮件管理(有源码)

    开始 邮件管理通常用在各个内部系统中,为了方便快捷的使用现有的代码开发一个邮件管理系统而诞生的. 准备条件 这是我的设计表结构,大家一看就懂了 --邮件接收表CREATE TABLE [dbo].[T ...

  8. stl vector 类

    目录 [-]说明构造方法例子vector 类中定义了4中种构造函数: · 默认构造函数,构造一个初始长度为0的空向量,如:vector<int> v1; · 带有单个整形参数的构造函数,此 ...

  9. 【转】基于 Apache 在本地配置多个虚拟主机

    如何使用 Apache 在本地配置出多个虚拟主机呢?而且使用不同的“域名”来访问本地不同的站点呢? 一般情况下,咱们都使用 localhost 来访问本机上的服务器,在我们的 C:/WINDOWS/s ...

  10. MyBatis拦截器打印不带问号的完整sql语句方法

    /* Preparing: SELECT * FROM tb_user WHERE id = ? AND user_name = ?  目标是打印:SELECT * FROM tb_user WHER ...