nyoj 322 117 求逆序数 归并排序
2016-05-17 17:51
190 查看
此题相当于问冒泡从小大大排序中交换了多少次,但是冒泡的时间复杂度的n^2,所以不可取,可以换用归并排序,归并排序时间复杂度为nlogn,还行,之前只听过归并排序的概念(毕竟有sort),没有敲过代码,这次参考别人的博客水一发,
比如现在有两组已经从小到大排好的数据 5 10 15 17和3 9 11 12 30
要将这两组数据整合到一起,同时按从小到大排序
那么可以先比较两组数据的第一个数字 5 和3,3小,取3,同时去掉3,再比较5 和9,取5同时去掉5,再比较10和9,9小取9同时去掉,以此类推,得到3 5 9 10 11 12 15 17 30 如果现在有一组数据要排大小的话,我们就可以将这一组数据分成两组,同时这两组的每一组再分成两组,直到每组数据为两个数(也可能为1个数),然后比较排序,这样就得到了已经排好序的数据,再两两比较类似于上面的例子,重新整合到一块。
概念容易理解,但是代码不是很好理解:
比如现在有两组已经从小到大排好的数据 5 10 15 17和3 9 11 12 30
要将这两组数据整合到一起,同时按从小到大排序
那么可以先比较两组数据的第一个数字 5 和3,3小,取3,同时去掉3,再比较5 和9,取5同时去掉5,再比较10和9,9小取9同时去掉,以此类推,得到3 5 9 10 11 12 15 17 30 如果现在有一组数据要排大小的话,我们就可以将这一组数据分成两组,同时这两组的每一组再分成两组,直到每组数据为两个数(也可能为1个数),然后比较排序,这样就得到了已经排好序的数据,再两两比较类似于上面的例子,重新整合到一块。
概念容易理解,但是代码不是很好理解:
#include<stdio.h> int a[1000010],b[1000010]; long long s=0; void sort(int first,int mid,int last) { int i=first,k=first,j=mid+1; while(i<=mid&&j<=last) //先将左一半或右一半的数据取完, { if(a[i]<=a[j]) b[k++]=a[i++]; else s+=j-k,b[k++]=a[j++]; //s+=j-k是关键,想想为什么,^_^ } while(i<=mid) //剩下的数据均是大的,所以取完 因为不知道到底是左一半先取完还是右一半先取完,所以两者都尝试 b[k++]=a[i++]; while(j<=last)//剩下的数据均是大的,所以取完 b[k++]=a[j++]; for(i=first; i<=last; i++) //再重新将b[]赋值给a[] a[i]=b[i]; } void msort(int first,int last) { int mid=(first+last)/2; if(first<last) //一直递归直到first==last msort(first,mid),msort(mid+1,last),sort(first,mid,last); //先把左一半和右一半排序,然后再整合 } int main() { int nn; scanf("%d",&nn); while(nn--) { int n,i; scanf("%d",&n); for(i=1; i<=n; i++) scanf("%d",&a[i]); s=0; msort(1,n); printf("%lld\n",s); } }
相关文章推荐
- Linux那些事儿之我是Sysfs(final)后记
- Jquery ajax 跨域访问
- 解决Eclipse建Maven项目module无法转换为2.3
- lua得到一个真随机数字
- HDU 1455 (dfs 强剪枝)
- 脑残的低级错误之静态成员变量
- 脑残的低级错误之静态成员变量
- 利用platform库获取浏览器和操作系统版本
- mysql问题汇总
- JVM调优- jmap(转)
- 使用Java和Scala在IDE中开发DataFrame实战
- Linux那些事儿之我是Sysfs(13)举例四:sysfs读入普通文件内容
- 标题QWER
- Flea travel<水题>
- 找window的三种方法
- JVM调优- jstat(转)
- Linux那些事儿之我是Sysfs(12)举例三:sysfs读入文件夹内容
- Hammer.js v1.0.5 在Surface上使用Chrome时,手指点击时放大
- lintcode --有效回文串
- 花了 7 天看了上千个交互动效神作,我总结出 5 个技巧