题目描述
设有一个数组 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
6
A=(4,3,0,5,1,2)
样例输出 Copy
B=(0,0,0,3,1,2)
提示
6
B=(0,0,0,3,1,2)
A=(4,3,0,5,1,2)
题意;
很简单,给你n个数,找出这个n个数的逆序数,或者反过来;
线性代数知识可以知道;任意一个数比在它前面任意的一个数大的数一共有多少个(记为s),那么s这个数就是这个数的逆序数。
① 给出数组A后,求出其编码(求即逆序数);
② 给出数组A的编码后,求出A中的原数据。 也就是给逆序数,让你求可以的出这个逆序数的数;
解题思路:
数据小,暴力即可。开两个数组,一个存入输入数据,另一个存入输出的数据;
对于①:
要从前往后找,一旦这个数比前面的一个数大,b数组下标为这个数的的值++,直到找完;
对于② :我们要从后面找,一旦s等于a1[i]并后面也没有出现过,说明这个数满足;
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string>
#include<queue>
#include<stack>
#include <math.h>
#include <string.h>
#define ll long long
#define inf 0x3f3f3f3f3f
#define N 1000005
char a[N];
int a1[N],b[N];
int vis[N];
ll cut;
using namespace std;
int main()
{
int n;
cin>>n;
int k=0;//简单的输入格式;
memset(vis,0,sizeof(vis));
char s;
getchar();
scanf("%c%s",&s,a);
if(s=='A')
{
for(int i=0; i<strlen(a); i++)
{
if(a[i]>='0'&&a[i]<='9')
{
a1[k++]=a[i]-'0';
}
}
for(int i=0; i<k; i++)//k个数
{
for(int j=0; j<i; j++)//j小于i,每次都是当前与它前面的数的比较
{
if(a1[i]>a1[j])//这个数a1[i]比前面的一个数大时
{
b[i]++;
}
}
}
cout<<"B=(";
for(int i=0; i<k; i++)
{
if(i<k-1)
cout<<b[i]<<",";
else if(i==k-1)
cout<<b[i]<<")";
}
}
else if(s=='B')
{
for(int i=0; i<strlen(a); i++)//之前用字符输入,所以都换成数字;
{
if(a[i]>='0'&&a[i]<='9')
{
a1[k++]=a[i]-'0';
}
}
int ss;
for(int i=k-1; i>=0; i--)从后往前
{
ss=0;//初始化
for(int j=0; j<k; j++)//代表k个
{
if(ss==a1[i]&&!vis[j])//当ss等于a1[i],标记后面也没有出现过;
{
b[i]=j;//存入这个数
vis[j]=1;
break;
}
if(!vis[j])//如果出现了
{
ss++;
}
}
}
cout<<"A=(";
for(int i=0; i<k; i++)
{
if(i<k-1)
cout<<b[i]<<",";
else if(i==k-1)
cout<<b[i]<<")";
}
}
return 0;
}