多人排成一个队列,我们认为从低到高是正确的序列,但是总有部分人不遵守秩序。如果说,前面的人比后面的人高(两人身高一样认为是合适的),那么我们就认为这两个人是一对“捣乱分子”,比如说,现在存在一个序列:
176, 178, 180, 170, 171
这些捣乱分子对为 <176, 170 >, <176, 171 >, <178, 170 >, <178, 171 >, <180, 170 >, <180, 171 >,
那么,现在给出一个整型序列,请找出这些捣乱分子对的个数(仅给出捣乱分子对的数目即可,不用具体的对)
要求:
输入:
为一个文件(in),文件的每一行为一个序列。序列全为数字,数字间用”,”分隔。
输出:
为一个文件(out),每行为一个数字,表示捣乱分子的对数。
详细说明自己的解题思路,说明自己实现的一些关键点。并给出实现的代码 ,并分析时间复杂度。
限制:
输入每行的最大数字个数为100000个,数字最长为6位。程序无内存使用限制。
解:此题的意思就是统计一个数组中的逆序对的个数为多少。根据归并排序算法的思想,可以对这个问题进行一下归并排序。然后就能统计出逆序对的个数。例如有16个数的数组,则进行归并排序的算法过程如下:
(0,1)(2,3)(0,3)(4,5)(6,7)(4,7)(0,7)(8,9)(10,11)(8,11)(12,13)(14,15)(12,15)(8,15)(0,15)
其中(0,1)表示数组中第0个数和第1个数进行合并。
代码如下:
/*
* 24_inversion.c
* Count inversions using merge sorting.
*
* Author: Yundeng Pan
* Date: 2009-7-11
* Email: intrepyd@gmail.om
* Blog: http://blog.csdn.net/intrepyd
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ARRAY_LENGTH 16
int merge_inversions(int *array, int p, int q, int r)
{
int n1, n2, i, j, k, count=0;
int *left=NULL, *right=NULL;
n1 = q-p+1;
n2 = r-q;
left = (int *)malloc(sizeof(int)*(n1));
right = (int *)malloc(sizeof(int)*(n2));
for(i=0; i<n1; i++)
{
left[i] = array[p+i];
}
for(j=0; j<n2; j++)
{
right[j] = array[q+1+j];
}
i = j = 0;
k = p;
while(i<n1 && j<n2)
{
if(left[i] <= right[j])
{
array[k++] = left[i++];
}
else
{
count += n1 - i;
array[k++] = right[j++];
}
}
for(; i<n1; i++)
{
array[k++] = left[i];
}
for(; j<n2; j++)
{
array[k++] = right[j];
}
free(left);
free(right);
left = NULL;
right = NULL;
return count;
}
int count_inversions(int *array, int p, int r)
{
int q, count=0;
if(p < r)
{
q = (int)((p+r)/2);
count += count_inversions(array, p, q);
count += count_inversions(array, q+1, r);
count += merge_inversions(array, p, q, r);
}
return count;
}
int main()
{
int i, count, array[ARRAY_LENGTH];
printf("/nOriginal array:/n");
srand(time(NULL));
for(i=0; i<ARRAY_LENGTH; i++)
{
array[i] = rand() % 20;
printf("%d ", array[i]);
}
count = count_inversions(array, 0, ARRAY_LENGTH-1);
printf("/n/nNumber of inversions is: %d/n/n", count);
return 0;
}