题目:https://codeforces.com/problemset/problem/1495/A
题意:
钻石矿工是一个类似黄金矿工的游戏,但是这个游戏中有n个矿工,而不是1个。
矿区可以描述为一个平面。n个矿工可以看作y轴上的n个点。矿区有n个钻石矿,我们可以把它们看作x轴上的n个点。出于某种原因,没有矿工或钻石矿可以在原点(点(0,0))。
每个矿工应该只开采一个钻石矿。每个矿工都有一个钩子,可以用来开采钻石矿。如果在点(a,b)的矿工使用他的钩子在点(c,d)开采钻石矿,他将花费两点之间距离能量来开采它。矿工们不能移动或互相帮助。
这个游戏的目的是最小化矿工花费的能量总和。你能找到这个最小值吗?
题解:依次让离原点最近的矿工开采最近的砖石,损耗的能量最少。能量的消耗也可以不用坐标计算只需记住—矿工记住y坐标,矿石记住x坐标。
#include <iostream>
#include <algorithm>
#include<cmath>
using namespace std;
typedef long long int ll;
const int N = 1e5 + 5;
double a[N];//矿工
double b[N];//砖石
int main()
{
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
int anum = 0, bnum = 0;
for (int i = 1; i <= 2 * n; i++)
{
int x, y;
cin >> x >> y;
if (x == 0)
{
if (y < 0)
a[anum++] = -y;
else a[anum++] = y;
}
else if(y == 0)
{
if (x < 0)
b[bnum++] = -x;
else b[bnum++] = x;
}
}
sort(a, a + anum);
sort(b, b + bnum);
double ans = 0;
for (int i = 0; i < n; i++)
{
ans += sqrt(pow(a[i], 2) + pow(b[i], 2));
}
printf("%.15lf\n",ans);
}
}