POJ2299-Ultra-QuickSort

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.
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

分析:

题意:
第一行给一个整数n,然后是n个乱序的数组序列,要求用冒泡排序的方法,要经过多少次交换才能变成升序排列?

解析:
大佬们说是求逆序数,逆序数我们会,但是这道题怎么变成逆序数的呢?

9 1 0 5 4
第一轮冒泡后:
1 0 5 4 9——交换4次,即9之后的四个数与9组成的逆序对的数量
第二轮冒泡后:
0 1 4 5 9——交换2次,即逆序对(1,0)和(5,4)

不难看出,一个数回到他升序的位置,即与他的逆序对中的另外一个数交换位置,有几对逆序对就交换几次,所以,就变成了对逆序数的求解!

然后这里a[i]与n的差距太大(0<=a[i]<=999999999,0<=n<=500000,如果我们开辟数组就要开辟很大的数组,但是输入却只有五十万个),所以要离散化处理!
离散化我就不详细讲了,我讲的也不行!_

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring> 
#define N 500050

using namespace std;

struct node{
	int v,id;
};

int tree[N];
int V[N]; 
node book[N];
int n;

bool cmp(node a,node b)
{
	return a.v<b.v;
}

int lowbit(int x)
{
	return x&-x;
}

void updata(int x)
{
	while(x<=n)
	{
		tree[x]+=1;
		x+=lowbit(x);
	}
}

int query(int x)
{
	int sum=0;
	while(x>0)
	{
		sum+=tree[x];
		x-=lowbit(x);
	}
	return sum;
}

int main()
{
	long long sum;
	while(scanf("%d",&n)&&n)
	{
		sum=0;
		memset(tree,0,sizeof(tree));
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&book[i].v);
			book[i].id=i;
		}
		sort(book+1,book+n+1,cmp);
		for(int i=1;i<=n;i++)
		{
			V[book[i].id]=i;
		}
		for(int i=1;i<=n;i++)
		{
			sum+=i-query(V[i])-1;
			updata(V[i]);
		}
		printf("%I64d\n",sum);
	}
	return 0;
}

注意:
这里输出格式要用%lld(391ms)或者%I64d(375ms).

发布了46 篇原创文章 · 获赞 16 · 访问量 416

猜你喜欢

转载自blog.csdn.net/weixin_43357583/article/details/104974608