问题 D: 编码问题

题目描述

设有一个数组 A,其中存放的元素为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; 
第二行输入有两种可能: 
例如: 
A=(4,3,0,5,1,2) 
或 
B=(0,0,0,3,1,2) 
其中输入中的逗号和括号都是英文状态下的。 


N <= 10 

 

输出

当输入的是A=(...),则输出其编码。 
当输入的是B=(...),则输出A中的原数据。 
输出数据的格式和输入数据的格式是一样的。 

 

样例输入

6
A=(4,3,0,5,1,2)

 

样例输出

B=(0,0,0,3,1,2)
6
B=(0,0,0,3,1,2)
------------------
A=(4,3,0,5,1,2)

思路:

把第二个A写成B了,贡献了一发wa,逆推感觉挺难的,从后往前看 , 编码后『0,0,0,3,1,2』
最后一个2表示 原数组前5位有两个比最后一位的数字小,又因为原数组是1到6的数字不重复,所以最后一位等于2。
再看倒数第二位1,说明原数组前4位有1个比倒数第二位小,只能是0比1小,所以倒数第2位为1。


算法就可以出来了
定义一个标志数组
伪码:
bool flag[n] = {false}; //表示数字是否被使用过了
for(int i = n-1 ; i >= 0 ; i--)
{
~~~~从flag中找到还未使用的第A1[i]个数字,他在flag中的序号就是A[i]
}

代码:

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define ll long long
#define mem(ar,num) memset(ar,num,sizeof(ar))
#define me(ar) memset(ar,0,sizeof(ar))
#define lowbit(x) (x&(-x))
#define IOS ios::sync_with_stdio(false)
#define DEBUG cout<<endl<<"DEBUG"<<endl;
#define STOP system("pause");
#define mod 9875321
using namespace std;
int n, a[100], b[100];
bool flag[1000];
int main() {
    cin >> n;
    char c;
    cin >> c;
    if(c == 'A') {
        cin >> c;
        cin >> c;
        for(int i = 0; i < n; i++) {
            scanf("%d,", &a[i]);
        }
        cin >> c;
        for(int i = 1; i < n; i++) {
            for(int j = 0; j < i; j++) {
                if(a[i] > a[j])
                    b[i]++;
            }
        }
        cout << "B=(";
        for(int i = 0; i < n - 1; i++) {
            cout << b[i] << ",";
        }
        cout << b[n - 1] << ")";
    } else {
        cin >> c;
        cin >> c;
        for(int i = 0; i < n; i++) {
            scanf("%d,", &a[i]);
            a[i]++;
        }
        cin >> c;
        for(int i = n - 1 ; i >= 0 ; i--) {
            int j = 0, k = 0;
            do {
                if(!flag[k])//k代表的是第j个未标记数所在位置
                    j++;
                k++;
            } while(j < a[i]);
            flag[--k] = 1;
            b[i] = k;
        }
        cout << "A=(";
        for(int i = 0; i < n - 1; i++) {
            cout << b[i] << ",";
        }
        cout << b[n - 1] << ")";
    }
    return 0;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值