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('\n');

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?'\n':' ');

42         else puts("No solution");

43     }

44     return 0;

45 }
View Code

 

你可能感兴趣的:(sequence)