设有一个数组 A:ARRAY[0..N-1] OF INTEGER;数组中存放的元素为0~N-1之间的整数,且A[i]≠A[j](当i≠j时)。
例如:
N=6时,有:A=(4,3,0,5,1,2)
此时,数组A的编码定义如下:
A[0]的编码为0;
A[i]的编码为:在A[0],A[1],……A[i-1]中比A[i]的值小的个数(i=1,2……N-1)
∴上面数组A的编码为:B=(0,0,0,3,1,2)
程序要求解决以下问题:
① 给出数组A后,求出其编码;
② 给出数组A的编码后,求出A中的原数据。
输入
每个测试文件只包含一组测试数据,每组输入包含三行。
第一行输入整数N,N<=12;
第二行输入有两种可能:
例如:
A=(4,3,0,5,1,2)
或
B=(0,0,0,3,1,2)
其中输入中的逗号和括号都是英文状态下的。
输出
当输入的是A=(...),则输出其编码。
当输入的是B=(...),则输出A中的原数据。
输出数据的格式和输入数据的格式是一样的。
样例输入 Copy
<span style="color:#333333"><span style="color:#333333">6
A=(4,3,0,5,1,2)
</span></span>
样例输出 Copy
<span style="color:#333333"><span style="color:#333333">B=(0,0,0,3,1,2)
</span></span>
提示
<span style="color:#333333"><span style="color:#333333">6
B=(0,0,0,3,1,2)
------------------
A=(4,3,0,5,1,2)</span></span>
来源/分类
解析:该题因为数据范围较小所以直接暴力查找就行了,我卡在不会寻找编码的原文。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
int s[100],s1[100];
int main()
{
int n;
scanf("%d",&n);
char a,b,c;
cin>>a>>b>>c;
cin>>s[1];
for(int i=2;i<=n;i++)
{
scanf(",%d",&s[i]);
}
cin>>b;
if(a=='A')
{
memset(s1,0,sizeof(s1));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=i;j++)
{
if(s[i]>s[j])
s1[i]++;
}
}
printf("B=(%d",s1[1]);
for(int i=2;i<=n;i++)
printf(",%d",s1[i]);
printf(")\n");
}
else//寻找编码的原文!!!!!
{
int vis[100],d=0;
memset(vis,0,sizeof(vis));
for(int i=n;i>=1;i--)//重点!!!!!让数组倒着查询
{
d=0;
/*循环解析:例B=(0,0,0,3,1,2),我们规定A中的6个数范围在[1,6]之间。
从后往前来,首先我们查找到了2,也就是说此时这个数在现在的数组中排
行第3大,因为这个数已经用过所以我们把它标记一下,证明不能再次使用
vis[j]=1。此时这个数组里可以看作只剩下5个数,我们现在又找到了1,说
明这个数在更新过后的数组里排行第2大,再次标记。之后就是重复上面的操
作直到找到所有数。*/
for(int j=1;j<=n;j++)
{
if(s[i]==d&&!vis[j])
{
s1[i]=j;
vis[j]=1;
break;
}
if(!vis[j])
d++;
}
}
printf("A=(%d",s1[1]);
for(int i=2;i<=n;i++)
printf(",%d",s1[i]);
printf(")\n");
}
}