算法导论_中位数与带权中位数。poj 1723

 定义:http://baike.baidu.com/view/1209446.htm

应用:http://blog.sina.com.cn/s/blog_51cea4040100fggh.html

证明:http://ufownl.blog.163.com/blog/static/125012220087314285867/

 

poj  1723

SOLDIERS
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 5361   Accepted: 1978

Description

N soldiers of the land Gridland are randomly scattered around the country.
A position in Gridland is given by a pair (x,y) of integer coordinates. Soldiers can move - in one move, one soldier can go one unit up, down, left or right (hence, he can change either his x or his y coordinate by 1 or -1).

The soldiers want to get into a horizontal line next to each other (so that their final positions are (x,y), (x+1,y), ..., (x+N-1,y), for some x and y). Integers x and y, as well as the final order of soldiers along the horizontal line is arbitrary.

The goal is to minimise the total number of moves of all the soldiers that takes them into such configuration.

Two or more soldiers must never occupy the same position at the same time.

Input

The first line of the input contains the integer N, 1 <= N <= 10000, the number of soldiers.
The following N lines of the input contain initial positions of the soldiers : for each i, 1 <= i <= N, the (i+1) st line of the input file contains a pair of integers x[i] and y[i] separated by a single blank character, representing the coordinates of the ith soldier, -10000 <= x[i],y[i] <= 10000.

Output

The first and the only line of the output should contain the minimum total number of moves that takes the soldiers into a horizontal line next to each other.

Sample Input

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

Sample Output

8

Source

 
题意: 在整数二维坐标系内站了若干个士兵,求将他们聚集在与x水平线平行且相邻的最小移动代价(移动只能上,下,左,右);
思路:将x与y分离
对于y,求即为权值相等的带权中位数;
对于x,思考下,最后的水平线一定是起于某点k(k是x坐标);
                   先对x排序下
         有,求和(0_to_n-1)(|xi-(k+i)|)=求和(0_to_n-1)(|(xi-i)-k|);很显然,答案就是对x数组进行 x[i]-=i;处理后求权值相等的带权中位数;
 
 1 #include <stdio.h>
2 #include <algorithm>
3 using namespace std;
4 int Abs(int a){return a>=0?a:-a;}
5 int main()
6 {
7 int n,i,j,x[10010],y[10010],sum=0;
8
9 scanf("%d",&n);
10 for(i=0;i<n;i++)
11 scanf("%d%d",x+i,y+i);
12
13 sort(x,x+n);
14 for(i=0;i<n;i++)
15 x[i]-=i;
16 nth_element(y,y+n/2,y+n);
17 nth_element(x,x+n/2,x+n);
18
19 for(i=0;i<n;i++)
20 sum+=Abs(x[i]-x[n/2])+Abs(y[i]-y[n/2]);
21 printf("%d\n",sum);
22 return 0;
23 }

你可能感兴趣的:(算法导论)