coj 数学作业(300)

[002]数学作业(300分)

Time Limit: 1000 ms     Memory Limit: 65536 KB
Total Submit: 14     Accepted: 5 
Description
小学的一道数学题
由N个正整数(1,2…N)组成的序列A,对于给定的序列A(a1,a2,...ai,...an),有一个确定的序列B(b1,b2,...bi,...bn)与之相对应,bi表示在序列A中数字i之前有bi个数字大于i。已知A,求B。
例:
已知A={4,5,3,1,2},求B
解得:
B={3,3,2,0,0}

在A中,1前面有4,5,3一共3个大于1的数,所以在B中b1 =3,同理,A中2前面也有3个大于它的数,所以B中b2=3 ,以此类推,得出B为{3,3,2,0,0}

话说Runner太喜欢抄作业了以至于把数学书都丢了……,可是这次作业数学老师要求抄题,这让Runner十分头疼。
现在请聪明的你设计一个程序,在只有答案序列B的情况下算出原题的序列A

 

Input
共2行
第一行:一个正整数N(N<500)
第二行:N个正整数,表示序列B(显然B中每个元素大小不可能大于N)

 

Output
只有一行,包括N个正整数,表示序列A,每两个数之间用空格隔开。

 

Sample Input
5
3 3 2 0 0

 

Sample Output
4 5 3 1 2
 
原来这是当年08级前辈选拔赛的题目,是模拟题。
解法:
1 2 3 4 5 初始时对应 0 0 0 0 0 
3 3 2 0 0
从前往后依次的调换顺序
对于1  调换3次 (后面比它大的就调换) 3 0 0 0 0
对于2  调换3次  3 3 0 0 0
。。。。
依次类推。
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
using namespace std;

int main()
{
    int A[1000],B[1000];
    int N;
    scanf("%d",&N);
    for(int i=1;i<=N;i++)
    {
        A[i]=i;
        scanf("%d",&B[i]);
    }

    for(int i=1;i<=N;i++)//对应B[i] i
    {
        if(B[i]==0) continue;
        for(int j=1;j<=N;j++)//对应排列 A[j]
        {
            if(A[j]==i)
            {
                while(--B[i]>=0)
                {
                    for(int k=j+1;k<=N;)
                    {
                        if(A[k]>A[j])
                        {
                            int temp=A[j];
                            A[j]=A[k];
                            A[k]=temp;
                            j=k;
                            break;
                        }
                        else
                        {
                            k++;
                        }
                    }
                }
                break;
            }
        }
    }
    for(int i=1;i<N;i++)
    {
        printf("%d ",A[i]);
    }
    printf("%d\n",A[N]);

  return 0;
}
posted @ 2012-04-25 20:47  索少  阅读(298)  评论(0编辑  收藏  举报