http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1201
定义Inversion 为 i<j && Ai>Aj
P 5 9 1 8 2 6 4 7 3
I 2 3 6 4 0 2 2 1 05前面有0个比5大的,输出的第5位是0
1前面有2个比1大的,输出的第1位是2
Permutation 和 Inversion 的转换
P to I :一个个数前面有多少个比它大的
I to P: 遍历n次
每次从头开始找到本次循环中第一个次数=0的数字
将这个数字放到输出数组的末尾
标记为已经找到(-1)
将这个数字之前的次数都减一
(....自己想出来的笨方法hhh...三层循环好像有点耗时)
#include <cstring>
#include <iostream>
using namespace std;
int main () {
int N;
while ( cin >> N && N ) {
char a;
int P[ 51 ], I[ 51 ]; // P输入数组,I输出数组
// Input
cin >> a;
for ( int i = 1; i <= N; i++ )
cin >> P[ i ];
switch ( a ) {
case 'P': { // P2I
for ( int i = 1; i <= N; i++ ) {
int cnt = 0;
for ( int j = 1; j <= i; j++ )
if ( P[ j ] > P[ i ] )
cnt++;
I[ P[ i ] ] = cnt;
}
break;
}
case 'I': { // I2P
int idx = 1; //记录I数组尾
for ( int i = 1; i <= N; i++ ) { //循环n次
for ( int j = 1; j <= N; j++ ) { //每次从头找到cnt = 0 的数
if ( P[ j ] == 0 ) {
I[ idx++ ] = j;
P[ j ] = -1; //标记为已经找到
for ( int k = 1; k <= j; k++ )
P[ k ]--; //比当前数小的数cnt-1,大的不变
break;
}
}
}
break;
}
}
// Output
for ( int i = 1; i <= N; i++ ) {
if ( i != 1 )
cout << " ";
cout << I[ i ];
}
cout << endl;
}
return 0;
}