士兵站位問題soliders

在一個劃分成網格的操場上,n個士兵散亂地站在網格點上。網格點由整數座標(x,y)表示。士兵們可以沿網格邊上、下、左、右移動一步,但在同一時刻任一網格點上只能有一名士兵。按照軍官的命令,士兵們要整齊地列成一個水平隊列,即排列成(x,y),(x+1,y),…,(x+n-1,y)。如何選擇x 和y的值才能使士兵們以最少的總移動步數排成一列。 計算使所有士兵排成一行需要的最少移動步數。

輸入

第1 行是油井數n,1< =n< =10000。接下來n 行是油井的位置,每行2個整數x和y,-10000< =x,y< =10000。

輸出

第1 行中的數是士兵排成一行需要的最少移動步數。

樣例輸入

5
1 2
2 2
1 3
3 -2
3 3

樣例輸出

8

解題思路:這道題其實跟郵局選址問題和油管問題很像,需要注意的是x方向的最近距離,士兵需要按照順序站位,因此第一個士兵的移動距離是|x1-x|,第二個士兵的移動距離是|x2-x-1|,即到最優點x的鄰近點的位置,因此總距離爲|x1-x|+|x2-x-1|+|x3-x-2|+...+|xn-n-n+1|,因此可求得最優點的x座標爲x1,x2-1...xn-n+1的中間值。

代碼如下:

#include<iostream>
#include <cstdio>  
#include <cstring>  
#include <cmath> 
#include<algorithm>
using namespace std;
#define N 10005
struct Soldier
{
	int x;
	int y;
}soldier[N],b[N];
int n,sum=0;
bool cmpx(const Soldier& a,const Soldier& b)
{
	return a.x<b.x;
}
 
 bool cmpy(const Soldier& a,const Soldier& b)
{
	return a.y<b.y;
}
bool cmpxy(int a,int b)
{
	return a<b;
}

int main()
{
	int px=0,py=0;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>soldier[i].x>>soldier[i].y;
	}
	memcpy(b,soldier,sizeof(b));
	sort(soldier,soldier+n,cmpy);
	py=soldier[n/2].y;
	sort(b,b+n,cmpx);
	for(int i=0;i<n;i++)
	{
		b[i].x=b[i].x-i;
	}
	sort(b,b+n,cmpx);
	px=b[n/2].x;
	sort(soldier,soldier+n,cmpx);
	for(int i=0;i<n;i++)
	{
		sum+=abs(soldier[i].x-px-i)+abs(soldier[i].y-py);
	}
	cout<<sum<<endl;
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章