HDU 2689 sort it

本文介绍了一种使用冒泡排序计算元素交换次数的方法,并提供了一种更高效的解决方案——利用树状数组和逆序数的概念来计算元素需要交换的次数。通过这两种不同的实现方式对比,展示了树状数组在处理此类问题时的优势。

此题就是求冒泡的次数,用冒泡做时间比较长,用树状数组做比较快

#include<stdio.h>
int num[1024],n;
int main( )
{
    while( scanf( "%d",&n ) != EOF )
    {
           for( int i = 0; i < n; ++i )
                scanf( "%d",&num[i] );
           int count = 0;
           for( int i = 0,f = 0; i < n - 1; ++i )
           {
                f = 0;
                for( int j = 0; j + 1< n - i; ++j )
                {
                     if( num[j+1] < num[j] )
                     {
                         int c = num[j+1];
                         num[j+1] = num[j];
                         num[j] = c;
                         f = 1;
                         ++count;
                     }
                 }
                 if( !f )
                     break;
            }
            printf( "%d\n",count );
           }
    return 0;
}

下面是用树状数组+逆序数的求法,这里就是把一个数插入到一个已经排好的的有序数列中,用plus来告诉来更新后面的点标记后面的数前面有多少个比他小的数,然后再用sum求有多少个比x小的数,而i表示目前数列中的总数,i-sum( x-1 )就算出有多少比x大的数,这样就算出x要交换多少次,s算出来即是最终结果了;

#include<stdio.h>
#include<string.h>
#define lowbit( x ) (x)&(-x)
int num[1024],n;
void plus( int x )
{
     while( x <= n )
     {
            ++num[x];
            x += lowbit( x );
            }
 }
int sum( int x )
{
    int s = 0;
    while( x )
    {
           s += num[x];
           x -= lowbit( x );
           }
    return s;
}
int main( )
{
    while( scanf( "%d",&n ) != EOF )
    {
           memset( num,0,sizeof( num ) );
           int s = 0;
           for( int i = 0; i < n; ++i )
           {
                int x;
                scanf( "%d",&x );
                plus( x );
                s  += ( i - sum( x - 1 ) );
            }
            printf( "%d\n",s );
           }
    return 0;
}

转载于:https://www.cnblogs.com/Lvsi/archive/2011/04/05/2005804.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值