士兵站队问题

士兵站队问题

时间: 1ms        内存:64M

描述:

在一个划分成网格的操场上,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

提示:

参考答案(内存最优[1348]):

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define MN 10010
#define abs(a) ((a)<0?(-(a)):(a))
int X[MN],Y[MN];
int N,ans;
int main()
{
      int i,mx,my;
      while(scanf("%d",&N)!=EOF)
	{
            for(i=0;i<N;i++)
                   scanf("%d%d",X+i,Y+i);
		sort(Y,Y+N);
		sort(X,X+N);
            my=Y[N/2];
		for(i=0;i<N;i++) X[i]-=i;
		sort(X,X+N);
		mx=X[N/2];
		ans=0;
		for(i=0;i<N;i++){ans+=abs(Y[i]-my)+abs(X[i]-mx);}
            printf("%d\n",ans);
	}
	return 0;
}

参考答案(时间最优[8]):

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int main(){
	int n;
	cin>>n;
	int x[n+10];
	int y[n+10];
	for(int i=0;i<n;i++)
	{
		cin>>x[i];
		cin>>y[i];
	}
	sort(x,x+n);
	sort(y,y+n);
	for(int i=0;i<n;i++)
	{
		x[i]-=i;
	}
	int a,b;
	sort(x,x+n);
	if(n/2==0)
	{
		a=x[n/2]+x[n/2-1];
		b=y[n/2]+y[n/2-1];
	}
	else
	{
		a=x[n/2];
		b=y[n/2];	
	}

	int sum=0;
	for(int i=0;i<n;i++)
	{
		sum+=fabs(x[i]-a)+fabs(y[i]-b);
	}
	//cout<<a<<" "<<b<<endl;
	cout<<sum;
}

题目和答案均来自于互联网,仅供参考,如有问题请联系管理员修改或删除。

点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注