NYOJ 1274排兵布阵
来源:互联网 发布:餐饮取名软件 编辑:程序博客网 时间:2024/09/21 09:26
排兵布阵
时间限制:1000 ms | 内存限制:65535 KB
难度:2
- 描述
- 在一个划分成网格的操场上,n个士兵散乱的站在网格上,网格点由整数坐标(x,y)表示,士兵们可以沿网格边上、下、左、右移动一步,但在同一时刻任一网格点上只能有一名士兵。按照将军的命令,士兵们要整齐的排列成一个水平队列,即排列成(x, y),(x+1, y),……,(x+n-1, y)。如何选择x和y的值才能使士兵们以最少的总移动步数排成一行。请计算使所有士兵排成一行需要的最少移动步数。
- 输入
- 多组测试数据。
每组数据的第一行是士兵数n,1≤n≤10000。接下来n行是士兵的位置,每行2个整数x和y,-10000≤x,y≤10000. - 输出
- 输出使所有士兵排成一行需要的最少移动步数。
- 样例输入
51 22 21 33 -23 3
- 样例输出
8
- 分析:在解答这个问题之前,我们先思考这样一个问题:有n个整数a[1], a[2], ……, a[n],对这n个数进行变形,使得a[1]=a[2]=……=a[n]=k。令sum=Sigma{ abs(a[i] - k)}(i=1,2,……,n)。求sum的最小值。
关于k的选择,可以证明当k选择这n个数的中位数时,sum最小(证明略)。解决了上面的问题,则这个问题就比较容易解决了。
在这个问题中,因为最后要把所有的士兵排列成(x, y),(x+1, y),……,(x+n-1, y)的形式,而y的值是相同的,并且X轴方向和Y轴方向的移动相互不影响,所以对于Y轴方向的处理,就和上面的问题相同了。
受到处理Y轴方向的启发,对于X轴方向上的处理,可以采取类似的方法,不同的就是每个士兵x的值并不相同,而是后一个比前一个大1。那么对于X轴上的处理,只需找出一个中间值mid,横坐标x比mid大的士兵都排列在mid右边,横坐标x比mid小的士兵都排列在mid左边,这样求出的结果就是X轴方向移动的最小值。最后将X轴方向和Y轴方向移动的最小值相加,结果就是最终的最小值。而mid就是所有士兵横坐标x的中位数。
参考代码:
#include <cstdio>#include <algorithm>using namespace std;const int MaxN = 1e4 + 10;struct Soldier { int x, y;} a[MaxN];// Y轴排序bool comp_y(Soldier A, Soldier B) { if(A.y != B.y) return A.y < B.y; return A.x < B.x;}// X轴排序bool comp_x(Soldier A, Soldier B) { if(A.x != B.x) return A.x < B.x; return A.y < B.y;}int main() { int n; while(~scanf("%d", &n)) { for(int i = 0; i < n; ++i) scanf("%d%d", &a[i].x, &a[i].y); sort(a, a + n, comp_y); int flag_y = a[n / 2].y; // 取得y的中位数 sort(a, a + n, comp_x); int flag_x = a[n / 2].x; // 取得x的中位数 int flag_id; for(int i = 0; i < n; ++i) { if(a[i].x == flag_x) { flag_id = i; break; } } int ans = 0; for(int i = flag_id, cur_x = flag_x; i < n; ++i, ++cur_x) // 右边 ans += (abs(a[i].x - cur_x) + abs(a[i].y - flag_y)); for(int i = flag_id - 1, cur_x = flag_x - 1; i >= 0; --i, --cur_x) // 左边 ans += (abs(a[i].x - cur_x) + abs(a[i].y - flag_y)); printf("%d\n", ans); } return 0;}
- 分析:在解答这个问题之前,我们先思考这样一个问题:有n个整数a[1], a[2], ……, a[n],对这n个数进行变形,使得a[1]=a[2]=……=a[n]=k。令sum=Sigma{ abs(a[i] - k)}(i=1,2,……,n)。求sum的最小值。
0 0
- NYOJ 1274排兵布阵
- hdu 排兵布阵
- hdu1166排兵布阵
- 排兵布阵也模式
- Hdu 1166 排兵布阵
- 排兵布阵&&线段树
- hdu 1166 排兵布阵
- 排兵布阵 线段树
- 项目管理-5-排兵布阵
- hdu4539 排兵布阵 状态DP
- HDOJ - 4559 排兵布阵 DP
- hdu(4539)排兵布阵
- 【搜索】方向数组不如排兵布阵
- cogs2080Asm_Def排兵布阵解题报告
- cogs2080. Asm_Def排兵布阵x
- hdoj1166_排兵布阵(线段树、树状数组)
- 郑厂长系列故事——排兵布阵
- HDU 1166 排兵布阵(线段树)
- CString 操作指南
- opencv 2.4.3 配置VS2010
- create操作符
- PHP 操作 Excel PHPExcel 详解
- 用Ant实现Java项目的自动构建和部署
- NYOJ 1274排兵布阵
- 两个类互相包含的问题
- this
- 题目都是浮云
- just操作符
- 数字带通传输系统——二进制数字调制
- Generating function
- 【C#】C#基础学习笔记
- 项目的build path的几个选型卡都是以什么意思?1Source 2Projects 3Libraries 4Order and Export