您的位置:首页 > 产品设计 > UI/UE

POJ2299 Ultra-QuickSort

2016-06-10 15:49 531 查看
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

5
9
1
0
5
4
3
1
2
3
0

Sample Output

6
0

Source

Waterloo local 2005.02.05

正解一:归并排序
解题报告:
  大概题意是求数列的冒泡排序排序次数,求逆序对的模板题。
  直接归并排序的时候统计一下就可以了。
  归并排序的提交记录:

15602638ljh20002299Accepted4220K188MSG++1401B2016-06-10 15:08:59
//It is made by jump~
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
#ifdef WIN32
#define OT "%I64d"
#else
#define OT "%lld"
#endif
using namespace std;
typedef long long LL;
const int MAXN = 500011;
int n,m;
int jump[MAXN];
int g[MAXN];
LL ans;

inline int getint()
{
int w=0,q=0;
char c=getchar();
while((c<'0' || c>'9') && c!='-') c=getchar();
if (c=='-')  q=1, c=getchar();
while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
return q ? -w : w;
}

inline void merge(int l,int mid,int r){
int i=l,j=mid+1;
int cnt=l;
while(i<=mid && j<=r) {
if(jump[i]<=jump[j])  g[cnt++]=jump[i++];
else{
g[cnt++]=jump[j++];
//ans+=mid-i+1;
ans+=(LL)mid; ans-=(LL)i; ans++;
}
}
while(i<=mid) g[cnt++]=jump[i++];
while(j<=r) g[cnt++]=jump[j++];
//for(;i<=mid;i++) g[cnt++]=a[i];
//for(;j<=r;j++) g[cnt++]=a[i];
for(i=l;i<=r;i++) jump[i]=g[i];
}

inline void gui(int l,int r){
if(l==r) return ;
int mid=(l+r)/2;
gui(l,mid); gui(mid+1,r);
merge(l,mid,r);
}

inline void solve(){
while(1) {
n=getint();
if(n==0) break;
for(int i=1;i<=n;i++) jump[i]=getint();
ans=0;
gui(1,n);
printf(OT"\n",ans);
}
}

int main()
{
solve();
return 0;
}


正解二:树状数组

解题报告:

  树状数组也是可做的。

  由于数字比较大,先离散化一下,然后按顺序插入,插入之后看看已经有多少个数比自己大了,统计一下就可以了。

  比归并排序慢好多哦。。。

Run IDUserProblemResultMemoryTimeLanguageCode LengthSubmit Time
15602746ljh20002299Accepted7932K532MSG++1256B2016-06-10 15:41:43
//It is made by jump~
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
#ifdef WIN32
#define OT "%I64d"
#else
#define OT "%lld"
#endif
using namespace std;
typedef long long LL;
const int MAXN = 500011;
int n,L;
LL ans;
int a[MAXN],u[MAXN];
int shu[MAXN],rank[MAXN];

inline int getint()
{
int w=0,q=0;
char c=getchar();
while((c<'0' || c>'9') && c!='-') c=getchar();
if (c=='-')  q=1, c=getchar();
while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
return q ? -w : w;
}

inline void update(int x,int val){
while(x<=L) {
shu[x]+=val;
x+=x&(-x);
}
}

inline LL query(int x){
LL total=0;
while(x>0) {
total+=shu[x];
x-=x&(-x);
}
return total;
}

inline void solve(){
while(1) {
n=getint();
if(n==0) break;
for(int i=1;i<=n;i++) u[i]=a[i]=getint();
ans=0;
memset(shu,0,sizeof(shu));
sort(u+1,u+n+1);
L=unique(u+1,u+n+1)-u-1;
for(int i=1;i<=n;i++) {
rank[i]=lower_bound(u+1,u+L+1,a[i])-u;
update(rank[i],1);
ans+=query(L)-query(rank[i]);
}

printf(OT"\n",ans);
}
}

int main()
{
solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: