LeeBlog

导航

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;
}

posted on 2011-04-05 14:23  LeeBlog  阅读(196)  评论(0编辑  收藏  举报