POJ 1723(中位数+连续排列)

 题目大意:有N个士兵,每个士兵开始站的坐标是(x,y),现在使得将N个士兵站在同一个水平线(即所有士兵的y坐标相同)并且x坐标相邻,每个士兵每次可以移动一个位置(分别在x和y方向移动)。求出最少的移动步数。

分析题目:首先这个是可以分开看的,横纵坐标没有联系。

Y坐标:仅仅求出一个简单的中位数即可,然后一次求出距离这个中位数的值。

X坐标:这里我主要想讲讲这个X坐标的排序。题目中要求,x坐标必须连续排列(不能够存在重叠),于是,在这里这个操作是:
                一,先将x的序列排序
                二,将每个x的序列减去当前的下标值;思考:这里为啥要这样操作?有这样一个操作之后就可以保证连续排列。(如果原来本身就是相邻的部分,那么这一部分就不存在了)
                三,再对新的x的序列进行排序,找到中位数,依次相减即可。

#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
const int N = 10000;
int x[N],y[N];
int main()
{
	int n,i,j;
	while(cin>>n)
	{
		for(i = 0;i<n;i++)
		cin>>x[i]>>y[i];
		sort(x,x+n);
		for(i = 0;i<n;i++)
		x[i] -= i;
		sort(x,x+n);
		sort(y,y+n);
		
		int ans,ansx,ansy;
		ans = 0;
		ansx = x[n/2];
		ansy = y[n/2];
		for(i = 0;i<n;i++)
		{
			ans += abs(x[i]-ansx);
			ans += abs(y[i]-ansy);
		}
		cout<<ans<<endl;
	}
	return 0;
 } 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值