afterward

导航

 

 

求排序的数最少的交换次数。只能相邻的交换。

归并排序算法:

View Code
#include<stdio.h>
#include<limits.h>

const int MAXN = 500000 + 10;
const int INF = INT_MAX;

long long tot;//tot为逆序数总数。
int arr[MAXN];

//将b数组中的元素复制到a数组中。
void CopyArray(int a[], int b[], int len, int left)
{
    for(int i = 0; i < len; i++)
    {
        a[left++] = b[i];
    }
}

//归并排序,合并两个子序列中的元素。
void Merge(int a[], int left, int right)
{
    int begin1, begin2, mid, k=0, len;
    begin1 = left;
    mid = (left+right)/2;
    begin2 = mid+1;
    len = right-left+1;
    int *b = new int[len];
    while(begin1 <= mid && begin2 <= right)
    {
        if(a[begin1] < a[begin2])
        {
            b[k++] = a[begin1++];
        }
        else
        {
            b[k++] = a[begin2++];
            tot += (mid - begin1 + 1);
            //当后面的有序序列中的元素小与前面的有序序列的元素,
            //那么总的逆序数要加上前面有序序列中剩余的元素的个数,
            //因为这些是有序的,所以加上的那些数每个都比后面的序列中参与比较的元素大。
        }
    }
    while(begin1 <= mid)
    {
        b[k++] = a[begin1++];
    }
    while(begin2 <= right)
    {
        b[k++] = a[begin2++];
    }
    CopyArray(a, b, len, left);
    delete b;
}

//归并排序。
void Msort(int a[], int s, int t)
{
    int m;
    if( s<t )
    {
        m = ( s+t ) /2;
        Msort(a, s, m);
        Msort(a, m+1, t);
        Merge(a, s, t);
    }
}

int main()
{
    int n;
    while(scanf("%d", &n), n)
    {
        tot = 0;
        for(int i = 0; i < n; i++)
        {
            scanf("%d", &arr[i]);
        }
        Msort(arr, 0, n-1);
        printf("%lld\n", tot);
    }
    return 0;
}

树状数组:

View Code
#include<iostream>
#include<algorithm>
#define M 500001
using namespace std;
int c[M],aa[M],n;                   //aa数组为排序后重新编号用
struct digit
{
    int num,id;
} a[M];                             //num为数的大小
bool cmp(digit a,digit b)
{
    return a.num<b.num;
}
int lowbit(int t)
{
    return t&(t^(t-1));
}
int sum(int t)
{
    int total=0;
    while(t>0)
    {
        total+=c[t];
        t-=lowbit(t);
    }
    return total;
}

void update(int t,int key)
{
    while(t<=n)
    {
        c[t]+=key;
        t+=lowbit(t);
    }
}
int main()
{
    int i,j;
    long long ans;
    while(scanf("%d",&n),n)
    {
        memset(c,0,sizeof(c));
        ans=0;
        for(i=1; i<=n; i++)
        {
            scanf("%d",&a[i].num);
            a[i].id=i;
        }
        sort(a+1,a+n+1,cmp);
        aa[a[1].id]=1;                                 //最小的数编号为1
        for(i=2; i<=n; ++i)
        {
            if(a[a[i].id].num!=a[a[i-1].id].num)      //如果前后两个数不等,则编号为下标
                aa[a[i].id]=i;
            else
                aa[a[i].id]=aa[a[i-1].id];            //否则编号与前一个相同
        }         //for(i=1;i<=n;i++) printf("%d ",aa[i]);
        for(i=1; i<=n; ++i)
        {
            update(aa[i],1);
            ans+=(sum(n)-sum(aa[i]));                 //每次累加该数前边比它大的数的个数
        }
        printf("%lld\n",ans);
    }
}

 

 

 

 

Ultra-QuickSort
Time Limit: 7000MS  Memory Limit: 65536K
Total Submissions: 27681  Accepted: 9924
Description

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

posted on 2012-08-10 12:39  afterward  阅读(238)  评论(0编辑  收藏  举报