CSUOJ 1555 Inversion Sequence

1555: Inversion Sequence

Time Limit: 2 Sec  Memory Limit: 256 MB
Submit: 107  Solved: 34

Description

For sequence i1, i2, i3, … , iN, we set aj to be the number of members in the sequence which are prior to j and greater to j at the same time. The sequence a1, a2, a3, … , aN is referred to as the inversion sequence of the original sequence (i1, i2, i3, … , iN). For example, sequence 1, 2, 0, 1, 0 is the inversion sequence of sequence 3, 1, 5, 2, 4. Your task is to find a full permutation of 1~N that is an original sequence of a given inversion sequence. If there is no permutation meets the conditions please output “No solution”.

Input

There are several test cases.
Each test case contains 1 positive integers N in the first line.(1 ≤ N ≤ 10000).
Followed in the next line is an inversion sequence a1, a2, a3, … , aN (0 ≤ aj < N)
The input will finish with the end of file.

Output

For each case, please output the permutation of 1~N in one line. If there is no permutation meets the conditions, please output “No solution”.

Sample Input

5
1 2 0 1 0
3
0 0 0
2
1 1

Sample Output

3 1 5 2 4
1 2 3
No solution

HINT

 

Source

解题:这个题目啊。。难读啊!

还是看例子吧


1 2 0 1 0

这个表示在1-N的排列中,存在这种排列,数字1前面只有1个数比他大,数字2前面只有2个比他大,数字3前面只有0个比他大,数字4前面只有1个比他大,数字5前面0个比他大。

所以答案 3 1 5 2 4

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 10010;
 4 vector<int>v;
 5 int d[maxn],n;
 6 int main(){
 7     while(~scanf("%d",&n)){
 8         for(int i = 1; i <= n; ++i)
 9             scanf("%d",d+i);
10         v.clear();
11         bool flag = true;
12         for(int i = n; i > 0; --i){
13             if(v.size() < d[i]){
14                 flag = false;
15                 break;
16             }
17             v.insert(v.begin()+d[i],i);
18         }
19         if(flag){
20             flag = false;
21             for(int i = 0; i < v.size(); ++i){
22                 if(flag) putchar(' ');
23                 printf("%d",v[i]);
24                 flag = true;
25             }
26             putchar('
');
27         }else puts("No solution");
28     }
29     return 0;
30 }
View Code

线段树找空位置插入。。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 10010;
 4 struct node {
 5     int lt,rt,pos;
 6 } tree[maxn<<2];
 7 int d[maxn],ans[maxn],n;
 8 bool flag;
 9 void build(int lt,int rt,int v) {
10     tree[v].lt = lt;
11     tree[v].rt = rt;
12     if(lt == rt) {
13         tree[v].pos = 1;
14         return;
15     }
16     int mid = (lt + rt)>>1;
17     build(lt,mid,v<<1);
18     build(mid+1,rt,v<<1|1);
19     tree[v].pos = tree[v<<1].pos + tree[v<<1|1].pos;
20 }
21 void update(int s,int v,int value) {
22     if(tree[v].lt == tree[v].rt) {
23         tree[v].pos = 0;
24         ans[tree[v].lt] = value;
25         return;
26     }
27     if(tree[v<<1].pos >= s) update(s,v<<1,value);
28     else if(tree[v<<1|1].pos >= s - tree[v<<1].pos) update(s-tree[v<<1].pos,v<<1|1,value);
29     else flag = false;
30     tree[v].pos = tree[v<<1].pos + tree[v<<1|1].pos;
31 }
32 int main() {
33     while(~scanf("%d",&n)) {
34         build(1,n,1);
35         flag = true;
36         for(int i = 1; i <= n; ++i) {
37             scanf("%d",d+i);
38             if(flag) update(d[i]+1,1,i);
39         }
40         if(flag) for(int i = 1; i <= n; ++i)
41             printf("%d%c",ans[i],i == n?'
':' ');
42         else puts("No solution");
43     }
44     return 0;
45 }
View Code
原文地址:https://www.cnblogs.com/crackpotisback/p/4379405.html