码迷,mamicode.com
首页 > 其他好文 > 详细

[POJ 1723]SOLDIERS(带权中位数问题)

时间:2014-11-05 13:04:20      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   ar   for   sp   div   2014   

题目链接:http://poj.org/problem?id=1723

最近因为在为NOIP 2014复习,一直没写啥题解。。。

这个题目的意思是给你n个士兵在棋盘里的坐标,要你将他们排成连续的一行(即与x轴平行),问你最少要将这些士兵移动多少步。

思路:设最终连续的一行的开头坐标为(linex,liney),终点坐标为(linex+n-1,liney)

将x坐标和y坐标分开讨论。

y坐标上,要让士兵移动步数最少,则liney=士兵们的y坐标的中位数

x坐标上士兵的移动步数=|x1-linex|+|(x2-1)-linex|+...+|(xn-n+1)-linex|。

x坐标上求最少移动步数对应的linex就是一个带权中位数问题,我们要找的linex就是这个带权中位数。

对x坐标进行排序,设排序后数组为x1‘,x2‘...xn‘

设tmp数组,tmp1=x1‘-0,tmp2=x2‘-(2-1),....tmpn=xn‘-(n-1)

对tmp数组再排序,linex就是tmp数组的中位数。

剩下求最少移动步数的过程很简单就不多废话了

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <cmath>

#define MAXN 10005

using namespace std;

int x[MAXN],y[MAXN];

int main()
{
    int n,liney,linex,ans=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&x[i],&y[i]);
    }
    sort(y+1,y+n+1);
    liney=y[(n+1)/2];
    for(int i=1;i<=n;i++)
        ans+=abs(y[i]-liney);
    sort(x+1,x+n+1);
    for(int i=1;i<=n;i++)
    {
        x[i]=x[i]-i;
    }
    sort(x+1,x+n+1);
    linex=x[(n+1)/2];
    for(int i=1;i<=n;i++)
    {
        ans+=abs(x[i]-linex);
    }
    printf("%d\n",ans);
    return 0;
}




[POJ 1723]SOLDIERS(带权中位数问题)

标签:style   blog   http   io   ar   for   sp   div   2014   

原文地址:http://blog.csdn.net/qpswwww/article/details/40820827

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!