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

poj 1723 SOLDIERS 带权中位数

时间:2018-01-20 11:06:43      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:std   problem   div   res   air   names   class   mes   坐标   

题目

http://poj.org/problem?id=1723

题解

带权中位数类型的题目~
可以先考虑降维,最后集合的y坐标,明显是y坐标的中位数的位置,容易求出y方向的贡献res_y。比较麻烦的是在x坐标上最后是要列成一排,而不是单独的一个点,我们可以假设最后集合的最左边的点是x,采用贪心的策略列出公式:res_x=sum(abs(xi-x-i))(i belongs to [0,n-1])。令zi=xi-i,就转化为res_x=sum(abs(zi-x)),这相当于求zi数列的中位数(因为我们没有把重叠的点合并,所以不是带权了,直接求中位数就好,一样的意思)。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn=10010;

pair<int,int> pt[maxn];

bool cmp(const pair<int,int>& a,const pair<int,int>& b){
    return a.second<b.second;
}

int n;

int main(){
    while(scanf("%d",&n)!=EOF){
        for(int i=0;i<n;i++){
            scanf("%d%d",&pt[i].first,&pt[i].second);
        }
        sort(pt,pt+n,cmp);
        int res=0;
        for(int i=0;i<n;i++){
            res+=abs(pt[i].second-pt[n/2].second);
        }
        sort(pt,pt+n);
        for(int i=0;i<n;i++){
            pt[i].first=pt[i].first-i;
        }
        sort(pt,pt+n);
        for(int i=0;i<n;i++){
            res+=abs(pt[i].first-pt[n/2].first);
        }
        printf("%d\n",res);
    }
    return 0;
}

poj 1723 SOLDIERS 带权中位数

标签:std   problem   div   res   air   names   class   mes   坐标   

原文地址:https://www.cnblogs.com/fenice/p/8319903.html

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