• Ultra-QuickSort POJ


    In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence
    9 1 0 5 4 ,

    Ultra-QuickSort produces the output
    0 1 4 5 9 .

    Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.

    Input

    The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 -- the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.

    Output

    For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.

    Sample Input

    5
    9
    1
    0
    5
    4
    3
    1
    2
    3
    0
    

    Sample Output

    6
    0

    题意:将一个序列从小到大排序,如果只能交换相邻的数,最少需要交换多少次
    思路:和冒泡排序一样,一个数需要交换的次数就是它的逆序对数,所以就是求总的逆序对的个数

    求逆序对可以用两种方法
    归并排序:
     1 #include<cstdio>
     2 #include<iostream>
     3 using namespace std;
     4 
     5 int n;
     6 const int maxn = 5e5+5;
     7 int num[maxn];
     8 typedef long long ll;
     9 
    10 ll Mersort(int l,int r)
    11 {
    12     int mid = (l+r)/2;
    13     int i=l,j=mid+1;
    14     int b[r-l+5];
    15     int k=1;
    16     ll ans = 0;
    17     while(i <= mid && j <= r)
    18     {
    19         if(num[i] <= num[j])
    20             b[k++] = num[i++];
    21         else
    22             b[k++] = num[j++],ans+=mid-i+1;
    23     }
    24     while(i <= mid)
    25     {
    26         b[k++] = num[i++];
    27     }
    28     while(j <= r)
    29     {
    30         b[k++] = num[j++];
    31     }
    32     for(int i=l; i<=r; i++)
    33     {
    34         num[i] = b[i-l+1];
    35     }
    36     return ans;
    37 }
    38 
    39 int Merge(int l,int r,ll  &ans)
    40 {
    41     int mid = (l+r)/2;
    42     if(l == r)
    43         return 0;
    44     Merge(l,mid,ans);
    45     Merge(mid+1,r,ans);
    46     ans += Mersort(l,r);
    47 }
    48 int main()
    49 {
    50     while(~scanf("%d",&n) && n)
    51     {
    52         for(int i=1; i<=n; i++)
    53             scanf("%d",&num[i]);
    54         ll  ans = 0;
    55         Merge(1,n,ans);
    56         printf("%lld
    ",ans);
    57     }
    58 }
    View Code

    树状数组:(要注意离散,离散可以二分,也可以map)
     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<string.h>
     5 using namespace std;
     6 
     7 const int maxn = 5e5+5;
     8 int n;
     9 int tree[maxn];
    10 typedef long long ll;
    11 
    12 int lowbit(int x)
    13 {
    14     return x&(-x);
    15 }
    16 
    17 void add(int x)
    18 {
    19     for(int i=x;i<=n;i+=lowbit(i))
    20     {
    21         tree[i]++;
    22     }
    23 }
    24 
    25 int Query(int x)
    26 {
    27     int ans = 0;
    28     for(int i=x;i>0;i-=lowbit(i))
    29     {
    30         ans+=tree[i];
    31     }
    32     return ans;
    33 }
    34 int query(int x,int n,int *b)
    35 {
    36     return lower_bound(b+1,b+1+n,x) - b;
    37 }
    38 int main()
    39 {
    40     while(~scanf("%d",&n) && n)
    41     {
    42         memset(tree,0,sizeof(tree));
    43         int a[n+1],b[n+1];
    44         for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i] = a[i];
    45         sort(b+1,b+1+n);
    46         int len = unique(b+1,b+1+n)-b-1;
    47         ll ans = 0;
    48         for(int i=1;i<=n;i++)
    49         {
    50             int pos = query(a[i],len,b);
    51             add(pos);
    52             ans +=  pos - 1 - Query(pos-1);
    53         }
    54         printf("%lld
    ",ans);
    55     }
    56 }
    View Code


  • 相关阅读:
    出现身份验证错误 要求的函数不受支持,又找不到加密Oracle修正(亲测有效)
    .NET 同步钉钉接口的排班,和审批,并用审批回改排班,上班还是休息,请假或加班上午下午
    C# .NET 遍历Json 形成键值对 取节点值key value
    .net日期类与UNIX时间戳的相互转换,长数字
    PB里取datawindow类型的窗口名称
    js,JQ设置div或标签控件鼠标不可点击
    sql在所有存储过程中查询包含某字符串的执行语句
    QTableView之一:基本使用
    LeetCode 1317. 将整数转换为两个无零整数的和
    C++如何限制类对象只能静态分配或者只能只能动态分配
  • 原文地址:https://www.cnblogs.com/iwannabe/p/10165562.html
Copyright © 2020-2023  润新知