poj1723 SOLDIERS(思维题-中位数/货仓选址问题)

题目

n(n<=1e4)个士兵,第i个士兵的位置(xi,yi),-1e4<=xi,yi<=1e4

把士兵安排到同一条水平线上,使之在竖直方向n个士兵相邻

最后排成(x,y),(x+1,y),...(x+n-1,y)的样子,移动的代价是曼哈顿距离

最小化移动代价和,输出这个和

思路来源

https://blog.csdn.net/flora715/article/details/81017961

题解

和东北赛三分写的题,和之前做过的abc的中位数/三分的题,都很像

货仓选址问题,一维上选择一个位置使得所有位置到此处和最小,此处可以用中位数搞

注意到二维是可以抽象成两个独立的一维问题的,互不影响

//以下思路,来自思路来源网址,代码部分
x方向:对所有x坐标从小到大排序,由于要移动步数最少,
所以【最终的x坐标相对位置】与【排序后的x坐标相对位置】相同。
设最终的x坐标起始位置为a,则:
x[0] -> a  (->表示移动)
x[1] -> a+1
....
x[n-1] -> a+n-1 
即 x[0] -> a
x[1]-1 -> a
x[2]-2 -> a
....
x[n-1]-n-1 ->a ... 将所有x[i]-i移动到相同位置。
于是重新计算x[i]=x[i]-i,然后重新进行排序。

移动步数最少,类似蚂蚁相遇的入门题,交叉认为是不交叉的挪动,所以相对位置不变

设出最后的位置后再求解,这题主要考察的思维,就是这里吧

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e4+10;
int n,x[maxn],y[maxn];
int ans,mid;
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);
	for(int i=1;i<=n;++i)
	x[i]=x[i]-i+1;
	sort(x+1,x+n+1);
	sort(y+1,y+n+1);
	mid=(n+1)/2;
	for(int i=1;i<mid;++i)
	ans+=x[mid]-x[i],ans+=y[mid]-y[i];
	for(int i=mid+1;i<=n;++i)
	ans+=x[i]-x[mid],ans+=y[i]-y[mid];
	printf("%d\n",ans);
	return 0;
} 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Code92007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值