Poj1723 Soldiers(蓝书刷题记录)

问题描述:给你n个士兵在棋盘里的坐标,要你将他们排成连续的一行(即与x轴平行),问你最少要将这些士兵移动多少步。
题解:对于y轴方向上的处理,显然是排序后找中位数。而x轴方向的因为要相邻,所以有点麻烦。考虑已排好序的x坐标,最终状态下他们的相对位置已经固定。
设最终状态下的第一个坐标为 X+1
则第一个点的最终坐标为X+1 从x[1]---->X+1
第二个点的最终坐标为X+1 从x[2]---->X+2
第三个点为最终坐标为X+2 从x[3]---->X+3
第四个点为最终坐标为X+3 从x[4]---->X+4
第五个点为最终坐标为X+4 从x[5]---->X+5

x[1] - 1---->X
x[2] - 2---->X
x[3] - 3---->X
x[4] - 4---->X
x[5] - 5---->X
问题转化为找到一个X 使得 移动最小 和y 轴的处理方式一样了。

#include<bits/stdc++.h>
 using namespace std;
const int MAXN=100000;
int x[MAXN],y[MAXN],n;
int main()
{
   scanf("%d",&n);
   for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]);
   sort(x+1,x+n+1); sort(y+1,y+n+1);
   for(int i=1;i<=n;i++) x[i]-=i;
   sort(x+1,x+n+1);
   int mid_x=x[(n+1)/2];
   int mid_y=y[(n+1)/2];
   int J1=0,J2=0;
   for(int i=1;i<=n;i++)
   {
   	J1+=abs(x[i]-mid_x);
   	J2+=abs(y[i]-mid_y);
   }
   cout<<J1+J2;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值