[002]数学作业(300分)
Time Limit: 1000 ms Memory Limit: 65536 KBTotal 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
由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)
第一行:一个正整数N(N<500)
第二行:N个正整数,表示序列B(显然B中每个元素大小不可能大于N)
Output
只有一行,包括N个正整数,表示序列A,每两个数之间用空格隔开。
Sample Input
5
3 3 2 0 0
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;
}