poj 2299 Ultra-QuickSort
2017-04-10 14:43
232 查看
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.
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
Sample Output
题意:就是说冒泡排序的时候的交换次数是多少。
思路:用树状数组,先把数据离散化一下,节省内存,为什么要用离散化呢,如果告诉你数据范围是10^9,数据量是10^4没法开那么大的数组,离散化之后,只需要开10^4
大小的数组就行了,然后按照初始位置放到树状数组里,进行计算就行了,因为不是区间求和,树状数组C标记为1,即代表此数已经放进树状数组里了。放进数组里之后判断
比其小的数是否已经在里面了,确定排序时移动的次数(实在不明白的话,先搞懂树状数组,然后手动模拟代码)。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n;
int c[500005];
int reflect[500005];
struct node {
int p;
int num;
} a[500005];
int cmp(node x,node y) {
return x.num < y.num;
}
int lowbit(int x) {
return x&(-x);
}
void build(int p,int num) {
while(p<=n) {
c[p]+=num;
p+=lowbit(p);
}
}
int sum(int x) {
int ans=0;
while(x>0) {
ans+=c[x];
x-=lowbit(x);
}
return ans;
}
int main() {
int i;
while(scanf("%d",&n)!=EOF && n) {
for(i=1; i<=n; i++) {
scanf("%d",&a[i].num);
a[i].p=i;//记录这个数据的初始位置
}
sort(a+1,a+1+n,cmp);//排序的目的就是为了方便进行离散化
memset(c,0,sizeof(c));
for(i=1; i<=n; i++) {
reflect[a[i].p]=i;//离散化,为了节省空间(因为开树状数组是根据数的大小开的数组)
}
long long ans=0;
for(i=1; i<=n; i++) {
build(reflect[i],1);
ans+=i-sum(reflect[i]);//判断放进去以后 比其小的数有没有被放进来,从而得到要换多少次
}
printf("%lld\n",ans);
}
}
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
60
题意:就是说冒泡排序的时候的交换次数是多少。
思路:用树状数组,先把数据离散化一下,节省内存,为什么要用离散化呢,如果告诉你数据范围是10^9,数据量是10^4没法开那么大的数组,离散化之后,只需要开10^4
大小的数组就行了,然后按照初始位置放到树状数组里,进行计算就行了,因为不是区间求和,树状数组C标记为1,即代表此数已经放进树状数组里了。放进数组里之后判断
比其小的数是否已经在里面了,确定排序时移动的次数(实在不明白的话,先搞懂树状数组,然后手动模拟代码)。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n;
int c[500005];
int reflect[500005];
struct node {
int p;
int num;
} a[500005];
int cmp(node x,node y) {
return x.num < y.num;
}
int lowbit(int x) {
return x&(-x);
}
void build(int p,int num) {
while(p<=n) {
c[p]+=num;
p+=lowbit(p);
}
}
int sum(int x) {
int ans=0;
while(x>0) {
ans+=c[x];
x-=lowbit(x);
}
return ans;
}
int main() {
int i;
while(scanf("%d",&n)!=EOF && n) {
for(i=1; i<=n; i++) {
scanf("%d",&a[i].num);
a[i].p=i;//记录这个数据的初始位置
}
sort(a+1,a+1+n,cmp);//排序的目的就是为了方便进行离散化
memset(c,0,sizeof(c));
for(i=1; i<=n; i++) {
reflect[a[i].p]=i;//离散化,为了节省空间(因为开树状数组是根据数的大小开的数组)
}
long long ans=0;
for(i=1; i<=n; i++) {
build(reflect[i],1);
ans+=i-sum(reflect[i]);//判断放进去以后 比其小的数有没有被放进来,从而得到要换多少次
}
printf("%lld\n",ans);
}
}
相关文章推荐
- POJ-2299 Ultra-QuickSort(树状数组)(离散化)
- POJ 2299 && ZOJ 2386 Ultra-QuickSort 线段树
- POJ 2299 Ultra-QuickSort (离散化+树状数组)
- POJ 2299 Ultra-QuickSort【线段树】
- poj 2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- Ultra-QuickSort(poj 2299归并排序)
- poj 2299 -- Ultra-QuickSort
- poj 2299 Ultra-QuickSort(归并排序)||(树状数组+离散化)
- poj 2299 Ultra-QuickSort(树状数组求逆序数)
- POJ 2299 Ultra-QuickSort 求逆序数 线段树或树状数组 离散化
- POJ 2299 Ultra-QuickSort
- poj - 2299 - Ultra-QuickSort(树状数组)
- POJ2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- poj_2299_Ultra-QuickSort_201407251113
- poj2299--B - Ultra-QuickSort(线段树,离散化)
- POJ 2299 Ultra-QuickSort(归并排序,树状数组,离散化)
- poj2299 Ultra-QuickSort ——线段树
- POJ_2299_Ultra-QuickSort