【发布时间】:2012-10-27 08:21:42
【问题描述】:
这是问题(链接:http://opc.iarcs.org.in/index.php/problems/FINDPERM):
数字 1, ..., N 的排列是这些数字的重新排列。例如
2 4 5 1 7 6 3 8
是 1,2, ..., 8 的排列。当然,
1 2 3 4 5 6 7 8
也是 1, 2, ..., 8 的排列。
与 N 的每个排列相关的是一个长度为 N 的特殊正整数序列,称为它的反转序列。该序列的第 i 个元素是严格小于 i 并且在此排列中出现在 i 右侧的数字 j 的数量。对于排列
2 4 5 1 7 6 3 8
反转序列是
0 1 0 2 2 1 2 0
第二个元素是 1,因为 1 严格小于 2,并且在这个排列中它出现在 2 的右边。同样,第 5 个元素是 2,因为 1 和 3 严格小于 5,但在此排列中出现在 5 的右侧,依此类推。
再举一个例子,排列的反转序列
8 7 6 5 4 3 2 1
是
0 1 2 3 4 5 6 7
在这个问题中,您将得到一些排列的反转序列。你的任务是从这个序列重建排列。
我想出了这个代码:
#include <iostream>
using namespace std;
void insert(int key, int *array, int value , int size){
int i = 0;
for(i = 0; i < key; i++){
int j = size - i;
array[ j ] = array[ j - 1 ];
}
array[ size - i ] = value;
}
int main(){
int n;
cin >> n;
int array[ n ];
int key;
for( int i = 0; i < n; i++ ){
cin >> key;
insert( key, array, i + 1, i);
}
for(int i = 0;i < n;i ++){
cout << array[i] << " ";
}
return 0;
}
它工作正常,并且对 70% 的测试用例给出了正确答案,但超过了剩余的时间限制。 有没有其他更快的算法来解决这个问题?
【问题讨论】:
-
"您可以假设 N ≤ 100000。"
-
如果不需要使用 C++,python 有集合、排列和重新排列(我认为它们的命名不同)。您还可以在 python 中的集合之间进行交叉联合和差异。如果你从未尝试过 python,那就试试吧,它对数学来说非常棒。