当前位置: 首页> 财经> 金融 > 榆林网络推广_制作网页时常用的网页有哪些_头条搜索_软件开发培训多少钱

榆林网络推广_制作网页时常用的网页有哪些_头条搜索_软件开发培训多少钱

时间:2025/8/16 12:42:34来源:https://blog.csdn.net/2402_87646581/article/details/147197547 浏览次数:0次
榆林网络推广_制作网页时常用的网页有哪些_头条搜索_软件开发培训多少钱

-----------------------------------------------------------------中位数-------------------------------------------------------

中位数有一个很好的性质:假设有一批数据,你想找一个数,使得这批数据与它差的绝对值的和最小,你猜它是谁?哈哈

在一个划分成网格的操场上,n 个士兵散乱地站在网格点上,由整数坐标 (x,y) 表示。

士兵们可以沿网格边上、下左右移动一步,但在同时刻任一网格点上只能有 1 名士兵。

按照军官的命令,他们要整齐地列成一个水平队列,即排成队列,即排成 (x,y),(x+1,y),…,(x+n−1,y)。请求出如何选择 x 和 y 的值才能使士兵们以最少的总移动步数排成一列。

输入格式

输入的第一行是一个整数,代表士兵数 n。

第 2 到 (n+1) 行,每行 2 个整数,第 (i+1) 行的整数 xi​,yi​ 代表第 i 个士兵的坐标。

输出格式

输出一行一个整数,代表答案。

输入输出样例

输入 #1复制

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

输出 #1复制

8

说明/提示

对于 100% 的数据,保证 1≤n≤10000,−10000≤x,y≤10000。

纵坐标处理

我们先看纵坐标(其实是纵坐标比较简单)

  • 我们假设士兵要移动到的目标纵坐标为m;

那么我们可以推导出一大堆的东西: 士兵在垂直于x轴方向上的移动距离为:

	|y1-m|+|y2-m|+|y3-m|+……+|yn-1-m|+|yn-m|

那么m取什么值最小呢?显而易见,就是y1~yn序列的中位数,实现代码如下:

	int rey;sort(y+1,y+n+1);if(!n%2) rey=(y[n/2]+y[n/2+1])/2;//!n%2意为 n%2 =0(在if语句里写2个'='),即 n%2 为假else rey=y[n/2+1];

横坐标处理

现在到了x麻烦了,因为有可能两位士兵的横坐标是相同的!而纵坐标的相同对于计算并没有影响!

~~~到这里实在不懂的要自己画下图了~~~

那接着怎么办?

  • ~~依旧假设~~~ ,我们假设第一位士兵站的位置是k,因为x从x1开始,那么我们假设成起始位置为k+1吧(不懂接着看完你就懂了)

那么:第二位士兵的位置是 k+2,接着是k+3,k+4,……,k+n;

所以,士兵横向(即平行于y轴方向)移动的距离为:

	|x1-(k+1)|+|x2-(k+2)|+|x3-(k+3)|+……+|x(n-1)-(k+n-1)|+|xn-(k+n)|

那么k取何值会使上式最小?我们不妨变形一下:

	|(x1-1)-k)|+|(x2-2)-k)|+|(x3-3)-k)|+……+|(x(n-1)-(n-1))-k)|+|(xn-n)-k)|//x(n-1)中 n-1 是x的下标

emmmm……于是又是中位数了!

结论:我们只需要取 k=xi-i的中位数就好了!

代码很容易实现,同纵坐标的的处理,先排序,但这次我们要将xi-i之后再次排序,再取中位数;

#include<iostream>

#include<algorithm>

using namespace std;

int x[10001],y[10001];

int work(int a,int b){

    return a>b?a-b:b-a;

}

int main(){

    int n,ans=0;

    cin>>n;

    for(int i=1;i<=n;i++) cin>>x[i]>>y[i];

    sort(x+1,x+n+1);

    sort(y+1,y+1+n);

    int mid_x,mid_y;

    for(int i=1;i<=n;i++) x[i]-=i;

    sort(x+1,x+n+1);

    if(n%2==0){

        int tmp=n/2;

        mid_x=(x[tmp]+x[tmp+1])/2;

        mid_y=(y[tmp]+y[tmp+1])/2;

    }else{

        int tmp=n/2;

        mid_x=x[tmp+1];

        mid_y=y[tmp+1];

    }

   

    for(int i=1;i<=n;i++){

       

        ans+=work(mid_x,x[i]);

        ans+=work(mid_y,y[i]);

    }

    cout<<ans<<endl;

    return 0;

}

关键字:榆林网络推广_制作网页时常用的网页有哪些_头条搜索_软件开发培训多少钱

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: