士兵站队问题
时间: 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;
}
题目和答案均来自于互联网,仅供参考,如有问题请联系管理员修改或删除。