Description
这个小岛在一个二维直角坐标系中描述。
你的任务就是帮gameboy找一个建造基地的位置,使矿工能以最快的速度采完所有矿。
Input
Output
Sample Input
Sample Output
1) 先考虑两个数的情况:y=|x-M|+|x-N| (M<=N)。根据两点之间线段距离最短,当x在[M, N]区间内任取一点,y都具有最小值|N-M|,当x不在[M, N]区间之内的时候,y>|N-M|
2) 再考虑n个数的情况。为了使y最小,x显然应该取在[A1, An]区域内。再根据1)的结论,在[A1, An]内取任何值,|x-A1|+|x-An|的大小都为|An-A1|
于是问题转变为求y=|x-A2|+|x-A3|+...|x-An-1|的最小值,x应该在[A2, An-1]内
这样逐层剥皮,最后剩下1个(对应n为奇数)或者2个数(对应n为偶数)。如果最后剩下1个数,那么x就应该取这个数,这个数显然为A1、A2、...An的中位数。如果最后剩下2个数,取这两个数构成的区域内任一个数都可以,特殊的,就取较小的那个数,它也是A1、A2、...An的中位数。
#include <iostream>
#include <algorithm>
using namespace std;
struct Point
{
double x, y;
}point[1000000];
bool com1(Point a, Point b)
{
return a.x > b.x;
}
bool com2(Point a, Point b)
{
return a.y > b.y;
}
int main()
{
int n;
while (cin >> n, n)
{
double x, y;
for (int i = 0; i < n; i++)
{
cin >> point[i].x >> point[i].y;
}
sort(point, point + n, com1);
x = (n % 2 == 0) ? (point[n / 2 - 1].x + point[n / 2].x) / 2 : point[n / 2].x;
sort(point, point + n, com2);
y = (n % 2 == 0) ? (point[n / 2 - 1].y + point[n / 2].y) / 2 : point[n / 2].y;
printf("%.2lf %.2lf\n", x, y);
}
return 0;
}