首页 > 代码库 > poj 2299 Ultra-QuickSort
poj 2299 Ultra-QuickSort
Ultra-QuickSort
Time Limit: 7000MS | Memory Limit: 65536K | |
Total Submissions: 38588 | Accepted: 13903 |
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
这道题可以用线段树做,也可以用归并排序做。
线段树做法:
把数组 9 1 0 5 4
映射为1 1 1 1 1,
查找最小值0之前的1个数为2,并把0位置的值改为0,数组改变为1 1 0 1 1
再查找次小值1之前1个数为1;并把1位置的值改为0,数组改变为1 0 0 1 1
重复操作,得到结果为2+1+2+1=6;
线段树 1032MS
#include"stdio.h" #include"stdlib.h" #define N 500005 struct st { int x,id; }b[N]; struct node { int l,r,s; }f[N*3]; int cmp(const void*a,const void*b) { return (*(struct st*)a).x-(*(struct st*)b).x; } void creat(int t,int l,int r) { f[t].l=l; f[t].r=r; if(l==r) { f[t].s=1; return ; } int temp=t*2,mid=(l+r)/2; creat(temp,l,mid); creat(temp+1,mid+1,r); f[t].s=f[temp].s+f[temp+1].s; } int find(int t,int l,int r) //查找1到id之间1的个数 { if(f[t].l>=l&&f[t].r<=r) return f[t].s; int temp=t*2,mid=(f[t].l+f[t].r)/2; if(mid>=r) return find(temp,l,r); else if(mid<l) return find(temp+1,l,r); else return find(temp,l,mid)+find(temp+1,mid+1,r); } void update(int t,int y) //把位置y的值改为0 { if(f[t].l==f[t].r) { f[t].s-=1; return ; } int temp=t*2,mid=(f[t].l+f[t].r)/2; if(mid>=y) update(temp,y); else update(temp+1,y); f[t].s=f[temp].s+f[temp+1].s; } int main() { int i,n; __int64 sum; while(scanf("%d",&n),n) { for(i=1;i<=n;i++) { scanf("%d",&b[i].x); b[i].id=i; } creat(1,1,n); // 建树,把各个点都记为1; b[0].x=-1; qsort(b,n+1,sizeof(b[0]),cmp); for(i=1,sum=0;i<=n;i++) { sum+=find(1,1,b[i].id); sum--; update(1,b[i].id); } printf("%I64d\n",sum); } return 0; }
二:归并排序做法 2079MS
#include"stdio.h" #define N 500005 const int inf=(int)1e10; int a[N]; __int64 sum; void count(int *a,int l,int mid,int r) { int i,j,k,n1,n2; n1=mid-l+1; n2=r-mid; int *ll=new int [n1+1]; //申请一段大小为n1+1的内存 int *rr=new int [n2+1]; for(k=0;k<n1;k++) ll[k]=a[l+k]; ll[k]=inf; for(k=0;k<n2;k++) rr[k]=a[mid+1+k]; rr[k]=inf; for(i=j=k=0;k<r-l+1;k++) { if(ll[i]<=rr[j]) { a[l+k]=ll[i]; i++; } else { a[l+k]=rr[j]; j++; sum+=(n1-i); } } delete ll; //释放内存空间 delete rr; } void mergesort(int *a,int l,int r) { //归并排序 if(l<r) { int mid=(l+r)/2; mergesort(a,l,mid); mergesort(a,mid+1,r); count(a,l,mid,r); } return ; } int main() { int i,n; while(scanf("%d",&n),n) { for(i=0;i<n;i++) scanf("%d",&a[i]); sum=0; mergesort(a,0,n-1); printf("%I64d\n",sum); } return 0; }
这个归并排序代码速度更快 360MS
#include"stdio.h" #define N 500005 int a[N],b[N]; __int64 sum; void mergesort(int l,int r) //数组从l到r,不包括右边界 { if(r-l<=1) return ; int mid=(l+r)/2; mergesort(l,mid); //不包括mid mergesort(mid,r); //从mid开始,不含r int i=l,j=mid,k=l; while(i<mid||j<r) { if(j>=r||a[i]<=a[j]&&i<mid) b[k++]=a[i++]; else { b[k++]=a[j++]; ans+=mid-i; } } for(i=l;i<r;i++) a[i]=b[i]; } int main() { int i,n; while(scanf("%d",&n),n) { for(i=0;i<n;i++) scanf("%d",&a[i]); sum=0; mergesort(0,n); printf("%I64d\n",sum); } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。