Permutation Recovery(排列恢复)

Problem Description
 
Professor Permula gave a number of permutations of the n integers 1, 2, ..., n to her students. For each integer i (1 <= i <= n), she asks the students to write down the number of integers greater than i that appears before i in the given permutation. This number is denoted ai. For example, if n = 8 and the permutation is 2,7,3,5,4,1,8,6, then a1 = 5 because there are 5 numbers (2, 7, 3, 5, 4) greater than 1 appearing before it. Similarly, a4 = 2 because there are 2 numbers (7, 5) greater than 4 appearing before it.

John, one of the students in the class, is studying for the final exams now. He found out that he has lost the assignment questions. He only has the answers (the ai's) but not the original permutation. Can you help him determine the original permutation, so he can review how to obtain the answers?
 

Input
 
The input consists of a number of test cases. Each test case starts with a line containing the integer n (n <= 500). The next n lines give the values of a1, ..., an. The input ends with n = 0.
 

Output
 
For each test case, print a line specifying the original permutation. Adjacent elements of a permutation should be separated by a comma. Note that some cases may require you to print lines containing more than 80 characters.
 

Sample Input
 
  
  
8 5 0 1 2 1 2 0 0 10 9 8 7 6 5 4 3 2 1 0 0
 

Sample Output
 
  
  
2,7,3,5,4,1,8,6 10,9,8,7,6,5,4,3,2,1
 


题目大意:给你n个数,第一个数表示在1之前有几个数比1大,即1的逆序数(线性代数中逆序数的概念),求原来这n个数是如何排列的。

 

思路:1 的位置最好排,1的逆序数是m,则1在原排列中的位置是m+1。按照1,2,3·····n的顺序找它们在原排列中的位置(原因是:举例来说,1 在排列中位置不影响2的逆序数,2的位置不影响3 的逆序数·····总之,在找k的位置时,1,2,3,···k-1 的位置都不影响k的逆序数,可忽略,而影响k逆序数的位置是那些还没有被占用的位置,所以从左往右遍历,遇到一个空格,k的逆序数减1(这个空格将来要放比k大的数),,当k的逆序数为-1时,此时的位置就是k在原排列中的位置。)

 

 

#include<stdio.h>
#include<string.h>
int main()
{
	int n;
	int a[1000];//存放n个数的逆序数 
	int b[1000];//存放原数列 
	while(scanf("%d",&n),n)
	{
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		for(int i=1;i<=n;i++)
		  scanf("%d",&a[i]);//i的逆序数是a[i] 
		for(int i=1;i<=n;i++)//在b[i]中找到依次1 —n的位置  
		{
			for(int j=1;j<=n;j++)
			{
				if(b[j]==0)
				{
					a[i]--;
					if(a[i]==-1)
					{
						b[j]=i;
						break;
					}
					   
				}
				  
				
			}
		}
		for(int i=1;i<n;i++)
		  printf("%d,",b[i]);
		  printf("%d\n",b[n]); 
	} 
	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值