Let { A1,A2,...,An } be a permutation of the set{ 1,2,..., n}. If i < j and Ai > Aj then the pair (Ai,Aj) is called an "inversion" of the permutation. For example, the permutation {3, 1, 4, 2} has three inversions: (3,1), (3,2) and (4,2).
The inversion table B1,B2,...,Bn of the permutation { A1,A2,...,An } is obtained by letting Bj be the number of elements to the left of j that are greater than j. (In other words, Bj is the number of inversions whose second component is j.) For example, the permutation:
{ 5,9,1,8,2,6,4,7,3 }
has the inversion table
2 3 6 4 0 2 2 1 0
since there are 2 numbers, 5 and 9, to the left of 1; 3 numbers, 5, 9 and 8, to the left of 2; etc.
Perhaps the most important fact about inversions is Marshall Hall's observation that an inversion table uniquely determines the corresponding permutation. So your task is to convert a permutation to its inversion table, or vise versa, to convert from an inversion table to the corresponding permutation.
Input:
The input consists of several test cases. Each test case contains two lines.
The first line contains a single integer N ( 1 <= N <= 50) which indicates the number of elements in the permutation/invertion table.
The second line begins with a single charactor either 'P', meaning that the next N integers form a permutation, or 'I', meaning that the next N integers form an inversion table.
Following are N integers, separated by spaces. The input is terminated by a line contains N=0.
Output:
For each case of the input output a line of intergers, seperated by a single space (no space at the end of the line). If the input is a permutation, your output will be the corresponding inversion table; if the input is an inversion table, your output will be the corresponding permutation.
Sample Input:
9 P 5 9 1 8 2 6 4 7 3 9 I 2 3 6 4 0 2 2 1 0 0
Sample Output:
2 3 6 4 0 2 2 1 0 5 9 1 8 2 6 4 7 3
分析:
已知集合的排列A[1…n]时,对于输入的每个数A[i],与之前的每个数比较,若存在更大的数,即符合k < i && A[k] > A[i],则B[A[i]]++;
已知排列的转化数组B[1...n]时,对于B[i],i前面有B[i]个比i大的数。如果按照从1到n的顺序还原排列,则对于数i,i之前的数可以判断。
先将A[1...n]初始化为0,假设数i在A[B[i] + 1]处,但是A[1...B[i]]中可能存在比i小的数,所以需要对其遍历一次,非0数有sum个,
则i的位置是A[B[i]+ sum + 1]。
代码:
#include <cstdio>
#include <cstring>
const int MAX_N = 51;
int N;
int A[MAX_N], B[MAX_N];
void disp(int a[]) {
for (int i = 1; i <= N; i++)
printf("%d%c", a[i], (i < N) ? ' ' : '\n');
}
void solve(char c) {
switch (c) {
case 'P':
for (int i = 1; i <= N; i++) {
scanf("%d", &A[i]);
for (int j = 1; j < i; j++)
if (A[j] > A[i])
B[A[i]]++;
}
disp(B);
break;
case 'I':
for (int i = 1; i <= N; i++) {
scanf("%d", &B[i]);
int sum = 0;
// for (int j = 1; j )
for (int j = 1; j <= N; j++) {
if (!A[j])
sum++;
if (sum == B[i] + 1) {
A[j] = i;
break;
}
}
}
disp(A);
break;
default :
;
}
}
int main() {
while (~scanf("%d", &N) && N) {
char c;
getchar();
scanf("%c", &c);
memset(A, 0, sizeof(A));
memset(B, 0, sizeof(B));
solve(c);
}
return 0;
}