题面
题意:
- 两个长度为n的序列,a序列从0到n-1.b序列里面的值的范围为[0,n-1],我们可以任意交换b序列里面的值的位置,使得从1到n两个序列差值的绝对值的根号值最小。
- 概括为:随机生成一个权值范围为 0~n-1 的序列,你要用 0~n-1 去和它匹配,匹配函数是 sqrt,要使得其根号和最小。要求平均情况下和标准值偏差不能超过 4%。
思路:
- 这道题目可以随便乱搞,我们可以直接重复冒泡的过程,如果当前两个值的根号和大于交换之和的根号和,就将其两个数字交换。这样子保证其始终再像最优状态转移,重复个三到四次,便可以使误差小于4%。
代码:
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 10;
int b[MAXN];
double sqt[MAXN];
int main() {
for (int i = 1; i <= 1050; i++) {
sqt[i] = sqrt(1.0 * i);
}
int t;
scanf("%d", &t);
while (t--) {
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &b[i]);
}
for (int k = 1; k <= 3; k++) {
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (sqt[abs(i - b[i])] + sqt[abs(j - b[j])] > sqt[abs(i - b[j])] + sqt[abs(j - b[i])]) {
swap(b[i], b[j]);
}
}
}
}
for (int i = 0; i < n; i++) {
printf("%d ", b[i]);
}
printf("\n");
}
return 0;
}