MiYu原创, 转帖请注明 : 转载自 ______________白白の屋
题目地址 :
http://acm.hdu.edu.cn/showproblem.php?pid=2689
题目描述:
其实就是求 冒泡排序时 的交换次数, 当然也可以求逆序数来解决问题, 下面是2份 代码:
代码
//直接冒泡排序求交换的次数
/*
Mail to : miyubai@gamil.com
My Blog : www.baiyun.me
Link : http://www.cnblogs.com/MiYu || http://www.cppblog.com/MiYu
Author By : MiYu
Test : 1
Complier : g++ mingw32-3.4.2
Program : HDU_2689
Doc Name : Sort it
*/
//#pragma warning( disable:4789 )
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <utility>
#include <queue>
#include <stack>
#include <list>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
using namespace std;
int N, num[1010];
inline void swap ( int &a, int &b ) {
a ^= b ^= a ^= b;
}
int bouble () {
int sum = 0;
for ( int i = 0; i < N; ++ i ) {
for ( int j = 1; j < N - i; ++ j ) {
if ( num[j-1] > num[j] ) {
swap ( num[j-1], num[j] );
++ sum;
}
}
}
return sum;
}
void print () {
for ( int i = 0; i < N; ++ i )
cout << num[i] << " ";
cout << endl;
}
int main ()
{
while ( scanf ( "%d", &N ) == 1 ) {
for ( int i = 0; i < N; ++ i ) {
scanf ( "%d", num + i );
}
printf ( "%d\n",bouble () );
// print ();
}
return 0;
}
//树状数组求逆序数法
/*
Mail to : miyubai@gamil.com
My Blog : www.baiyun.me
Link : http://www.cnblogs.com/MiYu || http://www.cppblog.com/MiYu
Author By : MiYu
Test : 1
Complier : g++ mingw32-3.4.2
Program : HDU_2689
Doc Name : Sort it
*/
//#pragma warning( disable:4789 )
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <utility>
#include <queue>
#include <stack>
#include <list>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
using namespace std;
int N,val,num[1010],low[1010];
void init () {
for ( int i = 0; i <= 1010; ++ i ) {
low[i] = i & ( -i );
}
}
void modify ( int x ) {
while ( x <= N ) {
++ num[x];
x += low[x];
}
}
int query ( int x ) {
int sum = 0;
while ( x > 0 ) {
sum += num[x];
x -= low[x];
}
return sum;
}
int main ()
{
init ();
while ( scanf ( "%d", &N ) == 1 ) {
memset ( num, 0, sizeof ( num ) );
int sum = 0;
for ( int i = 0; i < N; ++ i ) {
scanf ( "%d", &val );
modify ( val );
sum += i - query ( val - 1 );
}
printf ( "%d\n", sum );
}
return 0;
}
/*
Mail to : miyubai@gamil.com
My Blog : www.baiyun.me
Link : http://www.cnblogs.com/MiYu || http://www.cppblog.com/MiYu
Author By : MiYu
Test : 1
Complier : g++ mingw32-3.4.2
Program : HDU_2689
Doc Name : Sort it
*/
//#pragma warning( disable:4789 )
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <utility>
#include <queue>
#include <stack>
#include <list>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
using namespace std;
int N, num[1010];
inline void swap ( int &a, int &b ) {
a ^= b ^= a ^= b;
}
int bouble () {
int sum = 0;
for ( int i = 0; i < N; ++ i ) {
for ( int j = 1; j < N - i; ++ j ) {
if ( num[j-1] > num[j] ) {
swap ( num[j-1], num[j] );
++ sum;
}
}
}
return sum;
}
void print () {
for ( int i = 0; i < N; ++ i )
cout << num[i] << " ";
cout << endl;
}
int main ()
{
while ( scanf ( "%d", &N ) == 1 ) {
for ( int i = 0; i < N; ++ i ) {
scanf ( "%d", num + i );
}
printf ( "%d\n",bouble () );
// print ();
}
return 0;
}
//树状数组求逆序数法
/*
Mail to : miyubai@gamil.com
My Blog : www.baiyun.me
Link : http://www.cnblogs.com/MiYu || http://www.cppblog.com/MiYu
Author By : MiYu
Test : 1
Complier : g++ mingw32-3.4.2
Program : HDU_2689
Doc Name : Sort it
*/
//#pragma warning( disable:4789 )
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <utility>
#include <queue>
#include <stack>
#include <list>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
using namespace std;
int N,val,num[1010],low[1010];
void init () {
for ( int i = 0; i <= 1010; ++ i ) {
low[i] = i & ( -i );
}
}
void modify ( int x ) {
while ( x <= N ) {
++ num[x];
x += low[x];
}
}
int query ( int x ) {
int sum = 0;
while ( x > 0 ) {
sum += num[x];
x -= low[x];
}
return sum;
}
int main ()
{
init ();
while ( scanf ( "%d", &N ) == 1 ) {
memset ( num, 0, sizeof ( num ) );
int sum = 0;
for ( int i = 0; i < N; ++ i ) {
scanf ( "%d", &val );
modify ( val );
sum += i - query ( val - 1 );
}
printf ( "%d\n", sum );
}
return 0;
}