poj1723 排序+中位数

本文介绍了解决POJ1723问题的方法,采用排序加中位数策略来确定目标坐标,并通过计算绝对差值之和来求解最小移动步数,确保了路径的最优性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
 *  poj1723
 *  排序+中位数
 *  目的纵坐标很容易想到是中位数,其实横坐标也一样
 *  如果目的x坐标是a,a+1,a+2,那么移动步数应该是sum(|x[i] - a - i|)
 *  那么a是x[i] - i的中位数就可以了
 *  不用担心步数重复的问题;合理安排顺序一定可以保证步数够用,所有绕远都可以通过改变顺序的方法解决
 */

#include <iostream>
#include <stdlib.h>
using namespace std;

int abs(const int x, const int y){
    return (x > y) ? x-y : y-x;
}

int cmp(const void* a,const void* b){return *((int*)a)-*((int*)b);}

int x[10001],y[10001],xx[10001];
int main(){
    int n,count = 0,dest_x,dest_y;
    cin >> n;
    for(int i=0;i<n;++i){
        cin >> x[i] >> y[i];
    }

    qsort(y,n,sizeof(int),cmp);
    dest_y = y[n/2];
    qsort(x,n,sizeof(int),cmp);

    for(int i=0;i<n;++i){
        xx[i] = x[i] - i;
    }
    qsort(xx,n,sizeof(int),cmp);
    dest_x = xx[n/2];
    //cout << dest_x << " " << dest_y << endl;
    for(int i=0;i<n;++i){
        count += abs(xx[i],dest_x);
        count += abs(y[i],dest_y);
    }    

    cout << count << endl;

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值