poj.2299
来源:互联网 发布:linux 僵尸进程 编辑:程序博客网 时间:2024/05/22 10:44
这道题目线段树解决,不过也可以用逆序数解决,这里直接给出一个结论,一个偏续序列通过两两交换最终达到有序的最小交换次数=该序列的逆序数。那么什么是逆序数呢?
这里以题目中给出的例子做简单的介绍:
9 1 0 5 4,这里要从小到大排序,那么4的逆序数为2,因为5前面有9和5比它大,依此类推,5,0,1,9的逆序数分别为1,2,1,0,这样逆序数总共为6,所以我们的任务就是求逆序数了。实际上也可以直接用冒泡排序和插入排序做,因为他们的原理就是基于交换相邻元素的值,但是他们的时间复杂度为O(N^2),如果用他们,铁定超时。用改善版的冒泡也不行,时间复杂度依旧很高,用希尔排序,虽然时间复杂度可以满足题目要求,但其原理和插入并非完全一样,无法找到对应关系。所以要用到时间复杂度比较小的排序算法,首先是快排,但是其原理并非是交换相邻的两个元素的值,无法找到与逆序数对应的关系,故舍弃,堆排序也一样,最后想到的是归并排序,他们的时间复杂度都为O(nlogn),归并排序的原理也并非是交换相邻元素的值,其思想为先分后和,我们可以利用和的过程将逆序数求出,具体就不详述了,看代码,你就会明白。下面是代码:
#include <stdio.h>#include <stdlib.h>#include <iostream>#define Max 500010using namespace std;__int64 record[Max];__int64 ans;int n;void Merge(__int64 *p,int start,int middle,int end){ __int64 *temp=new __int64[end-start+1]; int i=start,j=middle+1,k=0; while(i<=middle && j<=end){ if(p[i]<=p[j]){ temp[k]=p[i]; k++,i++; } else{ temp[k]=p[j]; ans+=middle-i+1; k++,j++; } } while(i<=middle) temp[k++]=p[i++]; while(j<=end) temp[k++]=p[j++]; for(i=start;i<=end;i++) p[i]=temp[i-start]; delete []temp;}void Merge_sort(__int64 *p,int start,int end){ if(start<end){ int middle=(start+end)>>1; Merge_sort(p,start,middle); Merge_sort(p,middle+1,end); Merge(p,start,middle,end); }}int main(){ while(scanf("%d",&n),n){ for(int i=0;i<n;i++) scanf("%lld",&record[i]); ans=0; Merge_sort(record,0,n-1); printf("%lld\n",ans); } return 0;}
0 0
- POJ-2299-POJ 2299
- POJ 2299
- Poj 2299
- POJ 2299
- poj 2299
- poj 2299
- poj 2299
- poj.2299
- POJ 2299
- poj 2299
- poj-2299
- poj 2299
- poj-2299
- poj 2299
- POJ 2299
- poj 2299
- Poj 2299
- POJ 2299
- Fatal signal 11 (SIGSEGV) at 0x00000048 (code=1)
- proc/sys/net/ipv4/下各项的意义
- 黑马程序员_基础加强_类加载器
- 黑马程序员----多线程3
- mybatis学习 from : http://blog.csdn.net/fairyhawk/article/details/8617549
- poj.2299
- 苹果iOS 8最值得期待的十大特性:支持移动支付
- sql where 1=1和 0=1 的作用
- 解析阿里巴巴为什么选择赴美上市
- java设计模式(行为型)之迭代器模式
- 简要解析JavaBean.
- JavaScript Window- 浏览器对象模型和W3C
- 增长与利润,处于上升期的创业公司应选择哪个?
- spring错误 org.springframework.dao.DataAccessException cannot be resolved