感谢
Lstete
L
s
t
e
t
e
的讲解!!!
他们都好强啊都有260 我什么都没有.jpg
这个题目首先第一眼会想 minmax m i n m a x 搜索, 但是数据范围只能过暴力分,但是还是按这个方向想,一方最大化权值差,另一方最小化,可以发现如果两边加入一些相同的元素是不影响答案的,那么我们新定义一个点的权值为它连向所有的点的边权值和,那么我们发现如果两个点被 doe d o e 和 faker f a k e r 分别选取,那么两个集合权值会同时加上一次边权,相当于这条边没有被选取,而在同一个集合时,被加入了集合两次,那么我们就可以把新的点按照点权排序,两边同时选取当前最大值即可, 最后把双方权值相减再除以2就是答案 时间复杂度 O(n2) O ( n 2 )
还是给出题人点赞,这两天题目都很妙,想到了实现难度都不高,很有 NOIP N O I P 感觉,自己还是菜了一点啊233
Codes
#include<bits/stdc++.h>
#define For(i, a, b) for(register int i = a; i <= b; ++ i)
#define pf(x) (1ll * (x) * (x))
using namespace std;
const int maxn = 5000 + 10;
double a[maxn], res;
int x[maxn], y[maxn], n, m;
double juli(int X, int Y) {
return sqrt(pf(x[X] - x[Y]) + pf(y[X] - y[Y]));
}
void File() {
freopen("by.in", "r", stdin);
freopen("by.out", "w", stdout);
}
void Solve() {
scanf("%d", &n);
For(i, 1, n << 1)
scanf("%d%d", &x[i], &y[i]);
For(i, 1, n << 1)
For(j, 1, n << 1)
a[i] += juli(i, j);
sort(a + 1, a + n * 2 + 1);
for(int i = n * 2; i; i -= 2)
res += a[i] - a[i - 1];
printf("%.6f", res * 0.5);
}
int main() {
File();
Solve();
return 0;
}