POJ1723士兵站队问题
题目简述: POJ1723,N名士兵分散在不同位置,各自具有不相同的坐标{x,y},士兵每次可以沿x或y轴移动一步,若命令士兵沿平行x轴的方向排成一列,且移动过程中士兵位置不可重合,求N个士兵移动总数的最小值。
输入要求 先输入一个总数N, 后面输入N组xy坐标,如:
5
1 2
2 2
1 3
3 -2
3 3
输出要求 只需要输出总步数即可 如 : 8
题目分析
首先,面对这个问题,我们有如下三点疑问:
1、如何确定队列的具体位置
2、如何计算各个士兵移动的步数
3、如何保障移动过程中士兵不可重合
对于这三个疑问来看,确定了1我们才可以进一步去思索2,思索好了2,又要思索如何避免3,但实际上,N个士兵是可以凭借适当的移动方向和顺序来规避位置重合的情况发生,所以这里对于3的疑问大可以扔掉。
而抛开3的顾虑之后,我们已经不用纠结具体个人的移动,甚至可以拆分每个人的XY坐标,进行不同的讨论,所以对于2,我们可以分别求士兵到队列对应位置的X距离之和与Y距离之和,因一次移动距离为1,所以我们可以直接以距离代替步数。
而后,对于1问题,我们自然是优先考虑队列的y轴最优坐标,这里设设之为Y0,N个士兵各自的Y轴坐标我由小到大依次设为Y1,Y2,…,YN。
而各个士兵距离Y0线的垂直距离的和:S=|Y1-Y0|+|Y2-Y0|…+|YN-Y0|;
若欲有最短路径,也即S最小,则Y0为{Y1,Y2,Y3…Yn}的中位数,而非平均数,下图有证
如上图,中位数永远是所有数据内最中心位置的数,
于是恒有S=|Y1-Y0|+|Y2-Y0|…+|YN-Y0|=|Y1-Y0|+|YN-Y0|+|Y2-Y0|+|Y3-Y0|=|YN-Y1|+|Y3-Y2|
而相反,我们无法保证平均数一定在每对数据的中心,
如上图,平均数距离Y2,Y3的S为(15-5)+(15-3)=2*(15-5)+(5-3)=22。而如果取用中位数替代则S只为2.
了解到这一点,由于其他Y轴坐标都是已知数据,我们就可以确定Y0的大小。
而后,我们又要展开对队列X轴坐标的讨论,这里我们且设,X1到XN由小到大排序,队列最左端X轴坐标为X0,最右端为X0+n-1。
同上,
S=|X1-X0|+|X2-X0-1|+|X3-X0-2|+…+|XN-X0-N+1|
=|(X1)-X0|+|(X2-1)-X0|+|(X3-2)-X0|+…+|(XN-N+1)-X0|
此时,N与X1到XN的各个x坐标皆为已知数据,X0为未知数据,
欲求S最小,则同上X0为{X1,X2-1,X3-2,…,XN-N+1}的中位数
而中位数的求和在我国的小学教育里就已经全民普及,这里不做陈述。
分别求出
Sx与Sy,其和就为总步数,最后上代码(我写的有点繁琐)
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
struct pos{int x,y;
};
pos sol[10009];
bool rowy(pos a,pos b)
{return a.y<b.y;
}
bool rowx(pos a,pos b)
{return a.x<b.x;
}
int main()
{int num,i,line_x,line_y;int step=0;cin>>num;for(i=1;i<=num;i++)cin>>sol[i].x>>sol[i].y;sort(sol+1,sol+num+1,rowy);if(num%2==1)line_y=sol[(num+1)/2].y;elseline_y=(sol[num/2].y+sol[num/2+1].y)/2;for(i=1;i<=num;i++)step+=abs(sol[i].y-line_y); sort(sol+1,sol+num+1,rowx);int ad=0;for(i=1;i<=num;i++){sol[i].x-=ad;ad++;}sort(sol+1,sol+num+1,rowx);if(num%2==1)line_x=sol[(num+1)/2].x;elseline_x=(sol[num/2].x+sol[num/2+1].x)/2;for(i=1;i<=num;i++)step+=abs(sol[i].x-line_x); printf("%d",step);return 0;
}
POJ1723士兵站队问题相关推荐
- 算法设计与分析: 2-7 士兵站队问题
2-7 士兵站队问题 问题描述 在一个划分成网格的操场上,n个士兵散乱地站在网格点上.网格点由整数坐标(x,y)表示.士兵们可以沿网格边上.下.左.右移动一步,但在同一时刻任一网格点上只能有一名士兵. ...
- POJ - 1723 Soldiers 士兵站队 排序+中位数
[问题描述] 在一个划分成网格的操场上,n个士兵散乱地站在网格点上.网格点由整数最表(x,y)表示.士兵可以沿着网格边上.下.左.右移动一步,但在同一时刻一个网格上只能有一名士兵.按照军官的命令,士兵 ...
- luogu1889 士兵站队
luogu1889 士兵站队 时空限制 1000ms/128MB 题目描述 在一个划分成网格的操场上, n个士兵散乱地站在网格点上.由整数 坐标 (x,y) 表示.士兵们可以沿网 ...
- 【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取最小值. ...
最新文章
- linux查看所有用户 用户组的方法(修改用户组)
- linux 字符串加入中括号,方括号及其在命令行中的不同用法介绍
- 【模板】Manacher算法
- unsafehelper java_Java 9中将移除 Sun.misc.Unsafe
- freeradius 3.0 时间限制_创意营销3.0新模式下,易企秀要成为中国的Adobe
- 关于mmdetection上手的几点说明
- JS判断客户端是否是iOS或者Android
- 从零开始做Vue前端架构(2)
- MODBUS调试工具 C#源码 包含MODBUS主站调试工具和MODBUS从站调试工具
- python爬虫爬取视频时,实现实时进度条显示
- mASK调制在AWGN信道下的可达信息速率的积分计算法
- 如何解决Kettle读取txt文件时出现的中文乱码问题?
- PDF怎样转换成JPG图片 PDF转换为JPG图片教程
- 表格新增的属性及高级表单
- 阿里云函数计算使用教程
- 无https证书调用摄像头以及精伦读卡器IDR210-1调用安装
- 【Qt】QML快速入门7——输入元素
- 10G光猫生产测试时是选择中兴C300还是中兴C600 XGS-PON XG-PON GPON
- Atititjs h5调用摄像头视频聊天 拍照功能 相机功能 录像attilax总结
- mysql实训5答案_MySQL 实训篇 - osc_mi06gsf5的个人空间 - OSCHINA - 中文开源技术交流社区...