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; }
本人还是新手 ,转载请注明来自Lvsi‘s home