惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

罗磊的独立博客
Apple Machine Learning Research
Apple Machine Learning Research
The Cloudflare Blog
WordPress大学
WordPress大学
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 叶小钗
博客园 - 聂微东
阮一峰的网络日志
阮一峰的网络日志
腾讯CDC
博客园 - 三生石上(FineUI控件)
V
V2EX
有赞技术团队
有赞技术团队
V
Visual Studio Blog
小众软件
小众软件
Jina AI
Jina AI
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - Franky
量子位
T
Tailwind CSS Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
P
Palo Alto Networks Blog
Cisco Talos Blog
Cisco Talos Blog
I
Intezer
Project Zero
Project Zero
A
Arctic Wolf
P
Privacy International News Feed
V
Vulnerabilities – Threatpost
L
Lohrmann on Cybersecurity
S
Securelist
C
Cybersecurity and Infrastructure Security Agency CISA
C
CXSECURITY Database RSS Feed - CXSecurity.com
T
Tor Project blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
S
Security @ Cisco Blogs
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Google DeepMind News
Google DeepMind News
N
News and Events Feed by Topic
TaoSecurity Blog
TaoSecurity Blog
L
LINUX DO - 热门话题
G
GRAHAM CLULEY
Help Net Security
Help Net Security
N
News | PayPal Newsroom
W
WeLiveSecurity
G
Google Developers Blog
Microsoft Security Blog
Microsoft Security Blog
Engineering at Meta
Engineering at Meta
MongoDB | Blog
MongoDB | Blog
C
Check Point Blog

博客园 - 糖豆爸爸

【树上DP前导知识汇总】 快速幂、龟速乘总结 反向建图+拓扑排序 卡特兰数专题(Catalan) AcWing 126. 最大的和 AcWing 431. 守望者的逃离 AcWing 414. 数字游戏 AcWing 468. 魔法阵 AcWing 463. 求和 洛谷 P1632 点的移动 P1056 NOIP2008 普及组 排座椅 洛谷 P1862 输油管道问题 CF444C DZY Loves Colors P2253 好一个一中腰鼓! SCOI2010 P2572 序列操作 P4344 SHOI2015 脑洞治疗仪 T125847 【模板】动态开点线段树 P3373 【模板】线段树 2 Physical Education Lessons
洛谷 P1889 士兵站队
糖豆爸爸 · 2023-09-19 · via 博客园 - 糖豆爸爸

洛谷 \(P1889\) 士兵站队

问题简述

这道题我们可以换另一种思路去看待它,就容易理解了:

在一个平面上,把 \(n\) 个点排列在一条与 \(x\) 轴平行的直线的整点上,且相邻两点的距离为 \(1\)

求一种排列方案,使得这\(n\) 个点到目标位置的 曼哈顿距离和最小

解法综述

由于是求曼哈顿距离,所以可以将 \(x\) ,\(y\) 分开考虑。

首先,要找到最优的一列(使移动步数最少的一列),其实就是要找一条平行于\(x\)轴的直线,设此直线为\(y=k\),那么,每个点到这条线距离为\(|y_i-k|\),不难发现,当\(k\)是所有点纵坐标的中位数时,距离之和最小。

找到了这条直线之后,又该把每个点移到哪个位置才能使结果最优呢?

可以设最左边的点(第一个点)移动后的位置为\(b\),因为所有点必须排在一条线段上,那么第二个点的移动后的位置即为\(b+1\),第三个移动后的位置为\(b+2\)......以此类推,第\(n\)个点移动后的位置为\(b+n-1\)

那么横向移动的步数之和为\(|x_0-b|+|x_1-b-1|+|x_2-b-2|+......+|x_{n-1}-b-n+1|\),所以,要使步数之和最小,只需要 再找一次中位数 即可。

\(Code\)

#include <bits/stdc++.h>
using namespace std;
const int N = 10010;
int x[N], y[N];

int n, res;
int main() {
    cin >> n;
    for (int i = 0; i < n; i++) cin >> x[i] >> y[i];

    sort(y, y + n);
    sort(x, x + n);

    for (int i = 0; i < n; i++) res += abs(y[i] - y[n / 2]); // 对与x轴的一条平等线的最短距离和

    for (int i = 0; i < n; i++) x[i] -= i;

    sort(x, x + n);
    for (int i = 0; i < n; i++) res += abs(x[i] - x[n / 2]);

    // 输出
    cout << res << endl;
    return 0;
}