题目链接:
Ultra-QuickSort
Ultra-QuickSort算法处理一个由n个不相同整数组成的序列,通过交换序列中相邻两个整数从而使得序列达到升序排列。
比如输入:9 1 0 5 4
Ultra-QuickSort算法给出输出: 0 1 4 5 9
请算出Ultra-QuickSort算法需要进行多少次交换操作
输入:
输入数据包括多个case。每个case第一行是一个正整数 n < 500,000 ,表示输入长度,后面n行,每行是一个 999,999,999 以内的非负整数。
总时间限制: 10000ms 内存限制: 65536kB
Ultra-QuickSort算法处理一个由n个不相同整数组成的序列,通过交换序列中相邻两个整数从而使得序列达到升序排列。
比如输入:9 1 0 5 4
Ultra-QuickSort算法给出输出: 0 1 4 5 9
请算出Ultra-QuickSort算法需要进行多少次交换操作
输入:
输入数据包括多个case。每个case第一行是一个正整数 n < 500,000 ,表示输入长度,后面n行,每行是一个 999,999,999 以内的非负整数。
输入以n=0结束
每个case一行,表示交换操作的次数。
【题目分析】
比较显然的,这道题的本质是求逆序数。(可以通过考察总逆序数在描述中的排序算法操作时的行为发现)然后对时间的要求比较高,使用归并排序进行计算。需要注意的是输出可能会超过int范围。
【代码】
#include<stdio.h>
int In[600000];
int temp[600000];
long long int MergeCount (int l,int r)
{
if (r == l)
return 0;
int m = (l + r) / 2;
long long int ans = MergeCount(l, m) + MergeCount(m + 1, r);
int pa = l, pb = m + 1;
int pt = l;
while(pa != m + 1 || pb != r + 1)
{
if (pa == m + 1)
{
temp[pt] = In[pb];
pb++; pt++;
}
else if (pb == r + 1)
{
temp[pt] = In[pa];
pa++; pt++;
}
else if (In[pa] <= In[pb])
{
temp[pt] = In[pa];
pa++; pt++;
}
else if (In[pb] < In[pa])
{
temp[pt] = In[pb];
pb++; pt++; ans += m + 1 - pa;
}
}
for (int i = l; i <= r; i++)
In[i] = temp[i];
return ans;
}
int main ()
{
int n;
while(true)
{
scanf("%d", &n);
if (n == 0)
break;
for (int i = 0; i < n; i++)
scanf("%d", &In[i]);
printf("%lld\n", MergeCount(0, n - 1));
}
return 0;
}