Time Limit: 7000MS | Memory Limit: 65536K | |
Total Submissions: 39951 | Accepted: 14413 |
Description
In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence
9 1 0 5 4 ,
Ultra-QuickSort produces the output
0 1 4 5 9 .
Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.
Ultra-QuickSort produces the output
Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.
Input
The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 -- the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.
Output
For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.
Sample Input
5 9 1 0 5 4 3 1 2 3 0
Sample Output
6 0
Source
注意,数据比较大,使用long long输入输出;
归并排序:
摘自维基百科:
归并操作的过程如下:
- 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
- 设定两个指针,最初位置分别为两个已经排序序列的起始位置
- 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
- 重复步骤3直到某一指针到达序列尾
- 将另一序列剩下的所有元素直接复制到合并序列尾
归并排序具体工作原理如下(假设序列共有n个元素):
- 将序列每相邻两个数字进行归并操作,形成个序列,排序后每个序列包含两个元素
- 将上述序列再次归并,形成个序列,每个序列包含四个元素
- 重复步骤2,直到所有元素排序完毕
不断的递归,就像二分查找一样,故又叫做二路归并排序;
代码:
#include <iostream>
#include<stdio.h>
#define N 500001
using namespace std;
long long a[N],temp[N];
long long sum;
void sortarry(long long int a[],int s,int mid,int e)//合并左右数组集合
{
int i=s,j=mid+1,m=mid,n=e,k=0;
while(i<=mid&&j<=n)
{
if(a[i]<=a[j])//如果左边的小于右边的,则放到过度数组中
{
temp[k++]=a[i++];
}
else
{
temp[k++]=a[j++];
sum+=mid-i+1;//记录逆序数因为此时a[i]>a[j],会产生mid+1-i个倒序数(题目要求记录最小的交换次数)
}
}
while(i<=m)
{
temp[k++]=a[i++];
}
while(j<=n)
temp[k++]=a[j++];
for(i=0; i<k; i++)//将过度数组中的元素放到数组的左边
a[s+i]=temp[i];
}
void arrysort(long long int a[],int s,int e)
{
if(s<e)
{
int mid=(s+e)/2;
arrysort(a,s,mid);//递归使左边有序
arrysort(a,mid+1,e);//递归使右边有序
sortarry(a,s,mid,e);//合并左边和右边
}
}
int main()
{
int n,i;
while(~scanf("%d",&n)&&n)
{
sum=0;
for(i=0; i<n; i++)
scanf("%I64d",&a[i]);
arrysort(a,0,n-1);
printf("%I64d\n",sum);
}
return 0;
}