题目链接如下:
假设输入的所有排名是pre[i],其中pre[0]=0,那么我们每次倒过来取第pre[i]+1个数字就可以了。
目录
就和分析的一样,我们每次只要选出剩下的数组里边特定位置的数字就可以了。
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
- using namespace std;
-
- #define MAXN 20001
-
- int n;
- int pre[MAXN], ans[MAXN];
- int num[MAXN];
-
-
- int main(){
- scanf("%d",&n);
- pre[1]=0;
- for (int i = 2; i <= n; ++i) {
- scanf("%d",&pre[i]);
- }
- for (int i = 1; i <= n; ++i) {
- num[i]=i;
- }
- int k;
- for (int i = n; i > 0; --i) {
- k=0;
- for (int j = 1; j <= n; ++j) {
- if (num[j]!=-1){
- ++k;
- if (k==pre[i]+1){
- ans[i]=j;
- num[j]=-1;
- break;
- }
- }
- }
- }
- for (int i = 1; i <= n; ++i) {
- printf("%d\n",ans[i]);
- }
- return 0;
- }
用一颗树来维护区间,每个叶子节点代表的是某个数,那么我们相当于每次查找都维护这颗树就行了,并且还只要维护区间中点的个数就可以。
代码如下所示:
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
- using namespace std;
-
- #define MAXN 20001
- struct {
- int l,r,len;
- }tree[MAXN];
-
- int n;
- int pre[MAXN], ans[MAXN];
-
- void build_tree(int l,int r,int rt){
- tree[rt].l=l;
- tree[rt].r=r;
- tree[rt].len=r-l+1;
- if (l
- build_tree(l,(l+r)/2,rt<<1);
- build_tree((l+r)/2+1,r,rt<<1|1);
- }
- }
-
- int query(int num,int rt){
- tree[rt].len--;
- if (tree[rt].l==tree[rt].r){
- return tree[rt].l;
- }
- if (tree[rt<<1].len>=num){
- return query(num,rt<<1);
- } else{
- return query(num-tree[rt<<1].len,rt<<1|1);
- }
- }
-
- int main(){
- scanf("%d",&n);
- build_tree(1,n,1);
- pre[1]=0;
- for (int i = 2; i <= n; ++i) {
- scanf("%d",&pre[i]);
- // cout<
- }
- for (int i = n; i >= 1; --i) {
- ans[i]=query(pre[i]+1,1);
- }
- for (int i = 1; i <= n; ++i) {
- printf("%d\n",ans[i]);
- }
- return 0;
- }
3.完全二叉树实现线段树
这里用tree记录区间内剩下数字的数量,建立一颗完全二叉树。
代码如下所示:
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
- using namespace std;
-
- #define MAXN 20001
-
- int n;
- int pre[MAXN], ans[MAXN];
- int tree[4*MAXN];
-
- void build_tree(int last_left,int n){
- for (int i = last_left; i < last_left+n; ++i) {
- tree[i]=1;
- }
- while (last_left!=1){
- for (int i = last_left/2; i < last_left; ++i) {
- tree[i]=tree[i<<1]+tree[i<<1|1];
- }
- last_left/=2;
- }
- }
-
- int query(int num,int rt,int last_left){
- tree[rt]--;
- if (tree[rt]==0 && rt>=last_left){
- return rt;
- }
- if (tree[rt<<1]>=num){
- return query(num,rt<<1,last_left);
- } else{
- return query(num-tree[rt<<1],rt<<1|1,last_left);
- }
- }
-
- int main(){
- scanf("%d",&n);
- int last_left=1<<((int)(log((double)n)/ log(2.0))+1);
- build_tree(last_left,n);
- pre[1]=0;
- for (int i = 2; i <= n; ++i) {
- scanf("%d",&pre[i]);
- }
- for (int i = n; i > 0; --i) {
- ans[i]=query(pre[i]+1,1,last_left)-last_left+1;
- }
- for (int i = 1; i <= n; ++i) {
- printf("%d\n",ans[i]);
- }
- return 0;
- }