luogu1889 士兵站队
luogu1889 士兵站队
时空限制 1000ms/128MB
题目描述
在一个划分成网格的操场上, n个士兵散乱地站在网格点上。由整数 坐标 (x,y) 表示。士兵们可以沿网格边上、下左右移动一步,但在同时刻任一网格点上只能有名士兵。按照军官的命令,们要整齐地列成个水平队列,即排成 队列,即排成 (x,y),(x+1,y), …,(x+n -1,y) 。如何选择 x 和y的值才能使 士兵们以最少的总移动步数排成一列。
输入
输入的第 1 行是士兵数 n,1≤n≤10000 。接下来 n 行是士兵的初始位置, 每行 2 个整数 x 和y,-10000 ≤x,y≤10000 。
输出
输出只有一个整 数是士兵排成一行需要的最少移动步。
输入样例
5
1 2
2 2
1 3
3 -2
3 3
输出样例
8
分析(来自Bennettz)
一 士兵有多种移动方式
通过适当的移动顺序和移动路线可以使得同一时刻不会有两名士兵站在同一点
二 题目要求最佳移动方式(即求移动的最少步数)
题目要求转化为求士兵站立的“最终位置”,即如何取“最终位置”使得士兵移动的步数最少(最优)
Y轴方向上的考虑
设目标坐标为M,即n个士兵最终需要移动到的Y轴的坐标值为M
n个士兵的Y轴坐标分别为:
Y0,Y1,Y2 …… …… Yn-1
则最优步数S=|Y0-M|+|Y1-M|+|Y2-M|+ …… …… +|Yn-1-M|
结论:M取中间点的值使得S为最少(最优)
证明:……
从最上和最下的两个士兵开始递推……
最优位置
最优位置
归结到最后,处于中间位置的士兵的Y轴坐标值就是“最终位置”的Y轴坐标
可能有两种情况
士兵总数为双数情况:取中间两点间的任意一个位置
士兵总数为单数情况:取中间点的所在位置
解决办法:对所有的Y轴坐标进行排序(O(nlogn))或者进行线性时间选择(O(n))
然后取“中间”点的Y轴坐标值作为最佳位置M的值
最后通过公式求出Y轴方向上移动的最优步数
X轴方向上的考虑
首先需要对所有士兵的X轴坐标值进行排序
然后,按从左至右的顺序依次移动到每个士兵所对应的“最终位置”(最优),所移动的步数总和就是X轴方向上需要移动的步数
例,最左的士兵移动到“最终位置”的最左那位,第二个士兵移动到“最终位置”的第二位
则总的步数为:士兵一移动步数+士兵二移动步数+ …… +士兵n移动步数
如何确定X轴方向上的最佳的“最终位置”?
共n个士兵
他们相应的X轴坐标为:X0,X1,X2 …… …… Xn-1
设,士兵需要移动到的“最终位置”的X轴坐标值为:k,k+1,k+2 …… …… k+(n-1)
则所求最优步数S=|X0-k|+|X1- (k+1) |+|X2-(k+2)|+ …… +|Xn-1-(k+(n-1))|
经过变形S=|X0-k|+|(X1-1)-k|+|(X2-2)-k|+ …… …… +|(Xn-1-(n-1))-k|
注意到公式的形式与Y轴方向上的考虑一样,同样是n个已知数分别减去一个待定数后取绝对值,然后求和
因此还是采用取中位数的办法求得k值,最后算出最优解
代码
#include<iostream>
#include<cmath>
using namespace std;
const int N = 10005;
int x[N],y[N];void quicksort(int a[],int L,int R){int i,j,x;i=L; j=R; x=a[(i+j)/2];while (i<=j){while (a[i]<x) ++i;while (a[j]>x) --j;if (i<=j){int t=a[i]; a[i]=a[j]; a[j]=t;++i; --j;}}if (L<j) quicksort(a,L,j);if (i<R) quicksort(a,i,R);
}int main(){int n,ans=0;cin>>n;for (int i=1; i<=n; ++i) cin>>x[i]>>y[i];quicksort(y,1,n); quicksort(x,1,n);for (int i=1; i<=n; ++i) x[i]-=i;quicksort(x,1,n);for (int i=1; i<=n; ++i)ans += abs(x[i]-x[(1+n)/2])+abs(y[i]-y[(1+n)/2]);cout<<ans<<endl;return 0;
}
luogu1889 士兵站队相关推荐
- 算法设计与分析: 2-7 士兵站队问题
2-7 士兵站队问题 问题描述 在一个划分成网格的操场上,n个士兵散乱地站在网格点上.网格点由整数坐标(x,y)表示.士兵们可以沿网格边上.下.左.右移动一步,但在同一时刻任一网格点上只能有一名士兵. ...
- POJ - 1723 Soldiers 士兵站队 排序+中位数
[问题描述] 在一个划分成网格的操场上,n个士兵散乱地站在网格点上.网格点由整数最表(x,y)表示.士兵可以沿着网格边上.下.左.右移动一步,但在同一时刻一个网格上只能有一名士兵.按照军官的命令,士兵 ...
- POJ1723士兵站队问题
题目简述: POJ1723,N名士兵分散在不同位置,各自具有不相同的坐标{x,y},士兵每次可以沿x或y轴移动一步,若命令士兵沿平行x轴的方向排成一列,且移动过程中士兵位置不可重合,求N个士兵移动总数 ...
- 【P1889 士兵站队】(洛谷)
题目描述 在一个划分成网格的操场上,n个士兵散乱地站在网格点上,由整数坐标 (x,y)表示. 士兵们可以沿网格边上.下.左.右移动一步,但在同时刻任一网格点上只能有 1 名士兵. 按照军官的命令,们要 ...
- 【日常学习】【数学】codevs3625 士兵站队问题题解
题目描述 Description 在一个划分成网格的操场上,n个士兵散乱地站在网格点上.网格点用整数坐标(x,y)表示.士兵们可以沿网格边往上.下.左.右移动一步,但在同一时刻任一网格点上只能有一名士 ...
- 【排序专训】练习题 士兵站队(中位数应用) 解题报告
[问题描述] 在一个划分成网格的操场上,n个士兵散乱地站在网格点上.网格点由整数最表(x,y)表示.士兵可以沿着网格边上.下.左.右移动一步,但在同一时刻一个网格上只能有一名士兵.按照军官的 ...
- 中位数的应用—士兵站队问题
pku 1723--士兵战队问题 Description N soldiers of the land Gridland are randomly scattered around the count ...
- 《Free Pascal 语言与基础算法》_数据排序_9_士兵站队问题题解
题目描述 在一个划分成网格的操场上,n个士兵散乱地站在网格点上.网格点用整数坐标(x,y)表示.士兵们可以沿网格边往上.下.左.右移动一步,但在同一时刻任一网格点上只能有一名士兵.按照军官的命令,士兵 ...
- 士兵站队(pku1723)
http://acm.pku.edu.cn/JudgeOnline/problem?id=1723 一个定理:S=|x1-k|+|x2-k|+...+|xn-k|,当k为序列x的中位数时,S取最小值. ...
最新文章
- postmessage and sendmessage
- 树莓派debian配置lamp[解决Apache不显示php网页]
- Oracle sql解析类型, 软解析和硬解析浅析
- matlab中图像读写
- Java黑皮书课后题第1章:1.13(代数:求解2*2线性方程组)编写程序,求解以下方程组并显示x和y的值 3.4x+50.2y=44.5 2.1x+0.55y=5.9
- MYSQL数据库导入数据时出现乱码的解决办法
- python编写登录_通过Python编写一个简单登录功能过程解析
- 字符设备驱动 架构分析
- 剑指Offer值二叉树的深度
- 1337. 矩阵中战斗力最弱的 K 行
- 测试唯一ID支持多大的并发量
- 代码行数越少就越“简单”吗?
- 人工智能进场 AR/VR何去何从?
- RS232与RS485协议原理及其应用
- 木工雕刻机操作教学视频
- 什么是用户价值分层?
- TensorFlow卷积网络常用函数参数详细总结
- 案例(一)爬取优美图库风景壁纸
- 三防平板终端丨三防平板电脑丨三防平板如何应用在工业中?
- Win10部分引起鼠标卡顿间歇性失灵的原因
热门文章
- MYSQL Failed to initialize DD Storage Engine
- IBM Spectrum LSF 客户案例——国立巴黎高等矿业学院和软件开发公司 Transvalor
- Sinon教程:使用嘲弄,间谍和存根进行JavaScript测试
- AI创作教程之从 Youtube平台视频剪辑生成新闻文章 基于OpenAI Whisper、OpenAI GPT3 和 Stable Diffusion
- 【Android程序设计】 大作业:基于安卓的校园生活服务系统的设计与实现
- 水舞灯光秀在城市建设中有哪些作用呢
- python自动化测试视频教程_精品系列-悠悠python自动化测试视频教程
- 科研必备各专业全套模型:水文水资源、大气科学、农林生态、地信遥感、统计分析、编程语言等...
- 《计算机网络》第五章 运输层 ——TCP和UDP 可靠传输原理 TCP流量控制 拥塞控制 连接管理
- Greenplum的segment故障自愈小试