POJ 2299 Ultra-QuickSort
来源:互联网 发布:周易算法49 编辑:程序博客网 时间:2024/05/16 05:59
题目连接
大意: 只允许交换相邻两个数的情况下,问最少需要多少步完成排序(升序)操作?
分析: 模拟,推理后发现,对于每个逆序对都需要1次交换操作。而且可以证明:最优情况下也只需要交换逆序对。
简单说明一下:
①每个逆序对必须至少对应一次交换操作。
② 若当前没有逆序对,说明已经排好序了。
③选择两个数A , B交换, 若A,B为顺序,交换后产生了新的逆序对,需要的操作数至少加一;若A,B为逆序,则逆序对数量减一,一步步趋向升序。
问题就是求逆序对数,这里写了三种实现方法(效率:并归 > 树状数组 > 线段树):
线段树:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long LL;const int maxn=500050;#define Lson (cur)<<1,L,mid#define Rson (cur)<<1|1,mid+1,Rtypedef pair<int,int>PII;int T[maxn],Lisan[maxn],N;PII A[maxn];LL COUNT;int tree[maxn<<2];void update(int cur){ tree[cur] = tree[cur<<1] + tree[cur<<1|1];}void Insert(int cur,int L,int R,int P){ if(L==P && R==P){ tree[cur]++; return ; } int mid=(L+R)/2; if(P<=mid) Insert(Lson,P); else Insert(Rson,P); update(cur);}int Query(int cur,int L,int R,int l,int r){ if(l<=L && R<=r){ return tree[cur]; } int mid=(L+R)/2,ans=0; if(l<=mid) ans += Query(Lson,l,r); if(r>mid) ans += Query(Rson,l,r); return ans;}int main(){ while(~scanf("%d",&N) && N){ for(int i=1;i<=N;i++){ scanf("%d",&A[i].first); A[i].second=i; } sort(A+1,A+1+N); for(int i=1;i<=N;i++) { Lisan[A[i].second]=i; } memset(tree,0,sizeof(tree)); LL ans=0; for(int i=1;i<=N;i++){ int p=Lisan[i]; ans += Query(1,1,N+1,p+1,N+1); Insert(1,1,N+1,p); } printf("%I64d\n",ans); } return 0;}
树状数组:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long LL;typedef pair<int,int>PII;const int maxn=500050;int Lisan[maxn],C[maxn],N;PII A[maxn];int lowbit(int x){ return x&(-x);}void Insert(int i,int d){ while(i<=N){ C[i] += d; i += lowbit(i); }}int Query(int i){ int ans=0; while(i>0){ ans += C[i]; i -= lowbit(i); } return ans;}int main(){ while(~scanf("%d",&N) && N){ memset(C,0,sizeof(C)); for(int i=1;i<=N;i++){ scanf("%d",&A[i].first); A[i].second=i; } sort(A+1,A+N+1); for(int i=1;i<=N;i++){ Lisan[A[i].second]=i; } LL ans=0; for(int i=1;i<=N;i++){ Insert(Lisan[i],1); ans += Query(N)-Query(Lisan[i]); } printf("%I64d\n",ans); } return 0;}
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long LL;const int maxn=500050;int A[maxn],T[maxn],N;LL COUNT;void Merge_sort(int *A,int x,int y,int *T){ if(y-x <= 1) return ; int m=x+(y-x)/2,p=x,q=m,i=x; Merge_sort(A,x,m,T); Merge_sort(A,m,y,T); while(p < m || q < y){ if(q >= y || (p < m && A[p]<=A[q])) { T[i++]=A[p++]; } else { T[i++]=A[q++]; COUNT += m-p; } } for(i=x; i<y; i++) A[i]=T[i];}int main(){ while(~scanf("%d",&N) && N){ COUNT=0; for(int i=0;i<N;i++) scanf("%d",&A[i]); Merge_sort(A,0,N,T); printf("%I64d\n",COUNT); } return 0;}
- POJ 2299 Ultra-QuickSort
- poj 2299 Ultra-QuickSort
- poj 2299 Ultra-QuickSort
- poj 2299 Ultra-QuickSort
- poj 2299 Ultra-QuickSort
- poj 2299Ultra-quicksort
- POJ-2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- poj 2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- POJ 2299 - Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- ffdshow 源代码分析 2: 位图覆盖滤镜(对话框部分Dialog)
- C++中有关各种变量声明和定义的问题
- ajax原理和数据格式
- Discuz x2 直接爆出管理用户和密码
- MVC设计模型深入学习
- POJ 2299 Ultra-QuickSort
- c与指针(三)
- Java 单例模式探讨 (转)
- Source Insight 支持 PHP代码的详细设置
- 字符统计
- Discuz!所有版本通杀 存储型XSS 0day
- android学习_配置启动虚拟机
- myeclipse 8.5安装aptana插件
- C# 代码结构-大小写的区别