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 }
线段树找空位置插入。。
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 }