#返回上一级

@Author: 张海拔

@Update: 2014-01-14

@Link: http://www.cnblogs.com/zhanghaiba/p/3520089.html

  1. /*
  2. *Author: ZhangHaiba
  3. *Date: 2014-1-15
  4. *File: inverse_number.c
  5. *
  6. *this demo shows two method solving inverse number problem
  7. */
  8.  
  9. #include <stdio.h>
  10. #define N 512
  11. #define INF 0x7fffffff; //value of sentinel
  12. int array[N];
  13. int left_tmp[N/+];
  14. int right_tmp[N/+];
  15.  
  16. //public
  17. int inverse_number_cnt(int *, int);
  18. int inverse_number_cnt2(int *, int);
  19. void merge_sort(int *, int, int, int *);
  20. void set_array(int *, int);
  21. void show_array(int *, int);
  22.  
  23. int main(void)
  24. {
  25. int n;
  26.  
  27. scanf("%d", &n);
  28. set_array(array, n);
  29. int ans;
  30. ans = inverse_number_cnt(array, n);
  31. printf("%d\n", ans);
  32. ans = inverse_number_cnt2(array, n);
  33. printf("%d\n", ans);
  34. return ;
  35. }
  36.  
  37. int inverse_number_cnt(int *a, int n)
  38. {
  39. int i, j, cnt = ;
  40.  
  41. for (i = ; i < n-; ++i)
  42. for (j = i+; j < n; ++j)
  43. if (a[i] > a[j])
  44. ++cnt;
  45. return cnt;
  46. }
  47.  
  48. //modify merge_sort:
  49. //add variable cnt
  50. //add code "*cnt = left_len - i;"
  51. void merge_sort(int *a, int l, int r, int *cnt)
  52. {
  53. if (l >= r) return;
  54. else {
  55. int m = l + (r-l)/;
  56. merge_sort(a, l, m, cnt);
  57. merge_sort(a, m+, r, cnt);
  58. int left_len = m-l+, right_len = r-m, i, j = l;
  59. for (i = ; i < left_len; ++i, ++j)
  60. left_tmp[i] = a[j];
  61. left_tmp[i] = INF;
  62. for (i = ; i < right_len; ++i, ++j)
  63. right_tmp[i] = a[j];
  64. right_tmp[i] = INF;
  65. for (i = j = ; l <= r; ++l) {
  66. if (left_tmp[i] <= right_tmp[j])
  67. a[l] = left_tmp[i++];
  68. else {
  69. a[l] = right_tmp[j++];
  70. *cnt += left_len - i;
  71. }
  72. }
  73. }
  74. }
  75.  
  76. int inverse_number_cnt2(int *a, int n)
  77. {
  78. int l = , r = n-, cnt = ;
  79.  
  80. merge_sort(a, l, r, &cnt);
  81. return cnt;
  82. }
  83.  
  84. void set_array(int *a, int n)
  85. {
  86. int i;
  87.  
  88. for (i = ; i < n; ++i)
  89. scanf("%d", a+i);
  90. }
  91.  
  92. void show_array(int *a, int n)
  93. {
  94. int i;
  95.  
  96. for (i = ; i < n; ++i)
  97. printf(i == n- ? "%d\n" : "%d ", a[i]);
  98. }

逆序对的定义:序列A中,当位置i < j,而对应值a[i] > a[j],则称(i, j)构成序列A的一个逆序对。

解法一中,按照定义,通过两个for循环即可求出逆序对数。

即以第i个的元素为起点,j从i+1开始到n-1结束按定义进行验证,从而统计逆序对的个数,显然i的范围是[0, n-2]。

显然解法一的时间复杂度是O(n^2)。

解法二的所用函数几乎就是调用了一个纯粹的归并排序,目的通过计数器cnt的地址来修改cnt,做完归并排序后返回。

这个解法求逆序对数的原理是:对于某一次的归并(有序表的合并),类似二叉树的后序遍历,归并时当右子数组某个元素k进入根数组时,此时左子数组中,下标为i的元素以及它后面的所有元素都与k构成逆序对(左子数组的下标均<左子数组任何一个元素的下标,而k能进入根数组则说明它的值比左子数组剩下的所有元素都小,因此k的下标与上述元素的下标,均构成逆序对),所以有逆序对数要增加left_len - i,即:*cnt += left_len - i。

#返回上一级

怎样求逆序对数(Inverse Number)?的更多相关文章

  1. hdu 4911 求逆序对数+树状数组

    http://acm.hdu.edu.cn/showproblem.php?pid=4911 给定一个序列,有k次机会交换相邻两个位置的数,问说最后序列的逆序对数最少为多少. 实际上每交换一次能且只能 ...

  2. 归并排序(归并排序求逆序对数)--16--归并排序--Leetcode面试题51.数组中的逆序对

    面试题51. 数组中的逆序对 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出 ...

  3. 求逆序对数总结 & 归并排序

    用归并排序方式 最原始的方法的复杂度是O(n^2). 使用归并排序的方式,可以把复杂度降低到O(nlgn). 设A[1..n]是一个包含N个非负整数的数组.如果在i〈 j的情况下,有A〉A[j],则( ...

  4. poj 2299 树状数组求逆序对数+离散化

    Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 54883   Accepted: 20184 ...

  5. codeforces 459D D. Pashmak and Parmida's problem(离散化+线段树或树状数组求逆序对)

    题目链接: D. Pashmak and Parmida's problem time limit per test 3 seconds memory limit per test 256 megab ...

  6. codeforces 540E 离散化技巧+线段树/树状数组求逆序对

    传送门:https://codeforces.com/contest/540/problem/E 题意: 有一段无限长的序列,有n次交换,每次将u位置的元素和v位置的元素交换,问n次交换后这个序列的逆 ...

  7. 牛客练习赛33 D tokitsukaze and Inverse Number (树状数组求逆序对,结论)

    链接:https://ac.nowcoder.com/acm/contest/308/D 来源:牛客网 tokitsukaze and Inverse Number 时间限制:C/C++ 1秒,其他语 ...

  8. 归并求逆序数(逆序对数) && 线段树求逆序数

    Brainman Time Limit: 1000 MS Memory Limit: 30000 KB 64-bit integer IO format: %I64d , %I64u   Java c ...

  9. POJ2299Ultra-QuickSort(归并排序 + 树状数组求逆序对)

    树状数组求逆序对   转载http://www.cnblogs.com/shenshuyang/archive/2012/07/14/2591859.html 转载: 树状数组,具体的说是 离散化+树 ...

随机推荐

  1. 深入了解java虚拟机(JVM) 第十一章 类的加载

    一.类加载机制概述 虚拟机把描述类的数据从class文件加载到内存并对数据进行效验,解析和初始化,最终形成可以被虚拟机直接使用的java类型,这就是虚拟机的类加载机制. 二.类加载的机制 类加载的过程 ...

  2. php-fpm 和 nginx 的两种通信方式

    在 linux 中,nginx 服务器和 php-fpm 可以通过 tcp socket 和 unix socket 两种方式实现. 一下内容转自:https://blog.csdn.net/qq62 ...

  3. 洛谷P2664 树上游戏(点分治)

    传送门 题解 因为一个sb错误调了一个晚上……鬼晓得我为什么$solve(rt)$会写成$solve(v)$啊!!!一个$O(logn)$被我硬生生写成$O(n)$了竟然还能过$5$个点……话说还一直 ...

  4. flask后端获取前端post/get数据

    post:用request.form 而且要加上return !!记着加上return get:用 request.args()就可以了

  5. leetcode-887-三维形体投影面积

    题目描述: 在 N * N 的网格中,我们放置了一些与 x,y,z 三轴对齐的 1 * 1 * 1 立方体. 每个值 v = grid[i][j] 表示 v 个正方体叠放在单元格 (i, j) 上. ...

  6. leetcode-292-Nim Game(搬石子)

    题目描述: You are playing the following Nim Game with your friend: There is a heap of stones on the tabl ...

  7. SSAS有几种模式?

    SQL2012中两种,SQL2016好像有三种,下面的第三种好像是2016才有.

  8. python模块之 fabric

    Python模块之Fabric   Fabric简介 Fabric是一个Python库,可以通过SSH在多个host上批量执行任务.你可以编写任务脚本,然后通过Fabric在本地就可以使用SSH在大量 ...

  9. 【实战】Weblogic反序列化Getshell

    修仙就是干,直接操作起来 1.访问http://x.x.x.x:7001/wls-wsat/CoordinatorPortType 2.加入Content-Type:text/xml 3.在body中 ...

  10. java翻译到mono C#实现系列(4) 利用CountDownTimer类实现倒计时功能 mono版

    群里的朋友问利用CountDownTimer类实现倒计时功能怎么实现,我就百度了,参考http://blog.csdn.net/qq344429461/article/details/7521361写 ...