解题思路
枚举所有的可能的交换情况,时间复杂度 O ( n 4 ) O(n^4) O(n4)。
用归并排序计算数组的逆序对,时间复杂度 O ( n ) O(n) O(n)。
综上时间复杂度 O ( n 5 ) O(n^5) O(n5)。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int N = 55;
int n = 51;
int a[N], tmp[N];
int merge_sort(int q[], int l, int r)
{
if (l >= r)
return 0;
int mid = l + r >> 1;
int res = merge_sort(q, l, mid) + merge_sort(q, mid + 1, r);
int i = l, j = mid + 1, k = 0;
while (i <= mid && j <= r)
if (q[i] <= q[j])
tmp[k ++ ] = q[i ++ ];
else
tmp[k ++ ] = q[j ++ ], res += mid - i + 1;
while (i <= mid)
tmp[k ++ ] = q[i ++ ];
while (j <= r)
tmp[k ++ ] = q[j ++ ];
for (i = l, j = 0; j < k; ++ i, ++ j )
q[i] = tmp[j];
return res;
}
int main()
{
int cnt = 0, res = 0;
for (int i = 1; i <= n; ++ i )
for (int j = 1; j <= n; ++ j )
if (i != j)
for (int u = 1; u <= n; ++ u )
for (int v = 1; v <= n; ++ v )
if (u != v)
{
cnt ++;
for (int k = 1; k <= n; ++ k )
a[k] = k;
swap(a[i], a[j]);
swap(a[u], a[v]);
res += merge_sort(a, 1, n);
}
printf("%.2lf\n", (double)res / cnt);
return 0;
}
运行结果:
65.33