求解逆序数

逆序数求解,同于POJ2299题。

常规做法是使用O(N^2)的两重循环,逐个遍历

for i = (0, N)

for j = (i+1, N)

if(a[i] > a[j])

count++;

return count;

推荐的做法是使用类似于归并排序的方法,可以再O(NlogN)内算出。

输入格式:

5(个数) 9
1
0
5
4
3(个数)
1 2
3
0(个数为0表示结束)
1  #include<cstdio>
 2  #include<iostream>
 3  #include<fstream>
 4  using namespace std;
 5 
 6  #define MAX 1000000000
 7  #define N 500005
 8  
 9  long long a[N],b[N],c[N];
10  
11  inline long long Merge(int p,int q,int r)
12  {
13      long long cnt = 0 ;
14      for(int i=p;i<=q;i++)
15          b[i] = a[i];
16      for(int i=q+1;i<=r;i++)
17          c[i] = a[i];
18      b[q+1] = c[r+1] = MAX;
19      int bb = p, cc = q+1;
20      for(int i=p;i<=r;i++)
21      {
22          if(b[bb] <= c[cc])   //求逆序 需要写成<=
23          {
24              a[i] = b[bb++];
25          }
26          else
27          {
28              a[i] = c[cc++];
29              cnt += (q+1 - bb);        //主要是该步,只有b[bb] > c[cc],那么一定有 bb到q+1之间的数 大于 c[cc]。
30          }
31      }
32      return cnt;
33  }
34  
35  long long MergeSort(int p,int r)
36  {
37      long long cnt = 0;
38      if(p==r) return 0;
39      int q = (p+r)/2;
40      cnt += MergeSort(p,q);
41      cnt += MergeSort(q+1,r);
42      cnt += Merge(p,q,r);
43      return cnt;
44  }
45  
46  int main(int argc, char **argv)
47  {
48      ifstream fin(argv[1]);
49      int n;
50      while(1)
51      {
52          fin >> n;
53          if(!n)
54              break;
55          for(int i=0;i<n;i++)
56              fin >> a[i];
57          printf("%I64d\n",MergeSort(0,n-1));
58      }
59 
60      system("pause");
61      return 0;
62  }

原文链接: https://www.cnblogs.com/dandingyy/archive/2012/09/16/2688053.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/63011

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 上午10:42
下一篇 2023年2月9日 上午10:42

相关推荐