NOIP信息奥赛--1995“同创杯”初中复赛题题解(四)

NOI’95 “同创杯”全国青少年信息学(计算机)奥林匹克竞赛
分区联赛复赛测试数据(初中组)

第四题

问题:
编码问题:设有一个数组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中的原数据。

输出:

①由数组求编码:共15分(5%+5%+5%)
a 输入:N=6 A=(0,1,2,3,4,5)
输出: B=(0,1,2,3,4,5)

b 输入:N=6 A=(5,4,3,2,1,0)
输出: B=(0,0,0,0,0,0)

c 输入:N=8 A=(1,0,3,2,5,4,7,6)
输出: B=(0,0,2,2,4,4,6,6)

②由编码求原数组:共15分(5%+5%+5%)
a 输入:N=5 B=(0,0,0,0,0)
输出: A=(4,3,2,1,0)

b 输入:N=10 B=(0,1,2,3,4,5,6,7,8,9)
输出: A=(0,1,2,3,4,5,6,7,8,9)

c 输入:N=7 B=(0,0,0,0,4,5,6)
输出: A=(3,2,1,0,4,5,6)

解析
本题的是编码类型的题,难点在加解密的算法设计上。
首先要搞清楚加解密的原理,然后在进行程序上的设计。
相对而言,这道题加密的理解比较容易,解密是逆向推导,相对复杂了些。

具体代码:

#include <QCoreApplication>
#include<iostream>
#include<time.h>
using namespace std;

#define MAXN  100

int srcArray[MAXN];     //原文数组

int codeArray[MAXN];     //加密后产生的数组

int decodeArray[MAXN];   //解密后的数组

enum {CODEMODE = 0, DECODEMODE =1};

void GetRandom(int * random,int size);
void GetCode(int *arrayA,int *arrayB,int size);
void GetDecode(int *arrayA,int *arrayB,int size);

void printArray(int *parray,int size,int mode);

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    cout<<"Hello NOIP!"<<endl;

    cout<<"Enter the size of array:"<<endl;

    int size = 0;

    cin >>size;

    cout<< "The size of array is:"<<size<<endl;

    GetRandom(srcArray,size);               // 产生随机数列

    GetCode(srcArray,codeArray,size);        //加密

    printArray(codeArray,size,CODEMODE);     //打印密文

    GetDecode(codeArray,decodeArray,size);   //解密

    printArray(decodeArray,size,DECODEMODE);  //打印解密后的原文

    return a.exec();
}



// 随机产生个数为size的不同的数
void GetRandom(int *random,int size)
{
     int i, j[size], k;
     for (i = 0; i < size; i++)
     {
         j[i] = i;
     }
     for(i = 0; i < size; i++)
     {
         //生成第i个随机数
         srand((unsigned)time(NULL));

         k = (int)rand() % size;//k为下标

         //cout<<k<<" ";

         while (j[k] == -1)
         {
             k = (k + 1) % size;
         }
         random[i] = j[k];

         cout<< random[i]<< " ";

         j[k] = -1;
     }

     cout<<endl;
}

//加密算法
void GetCode(int *arrayA,int *arrayB,int size)
{
    arrayB[0]=0;

    int cnt = 0;
    for(int i = 1;i<size;i++)
    {
        for(int j = 0;j<i;j++)
        {
            if(arrayA[j]<arrayA[i])
            {
              cnt++;
              arrayB[i] = cnt;
            }

        }
        cnt = 0;
       // cout<< "The coded is:"<<arrayB[i]<<" ";
    }
}

//解密算法

void GetDecode(int *arrayA,int *arrayB,int size)
{
    int conf[size];    //参考数组

    for (int i = 0; i < size; i++)
    {
        conf[i] = i;
    }

    arrayB[size-1] = arrayA[size-1];  //确定最后一位数

    int temp = arrayB[size-1];

    conf[temp] = -1;

    int cnt = 0;

    for(int i = size-2;i>=0;i--)
    {
         for(int j = 0 ;j<size;j++)
         {
             if(conf[j]>=0)
             {
                cnt++;
                if(cnt == arrayA[i]+1)
                {
                  cnt = j;
                  break;
                }
             }
         }

         arrayB[i] =  conf[cnt];

         conf[cnt] =-1;

         cnt = 0;

    }
}



void printArray(int *parray,int size,int mode)
{
    if(mode == CODEMODE )
    {
     cout<< "The coded is:"<<endl;
    }
    else
    {
       cout<< "The decoded is:"<<endl;
    }

    for(int i=0;i<size;i++ )
    {
        cout<<parray[i]<<" ";
    }
    cout<<endl;
}

程序编译后输出:
在这里插入图片描述

原创文章 41 获赞 0 访问量 2052

猜你喜欢

转载自blog.csdn.net/qq_21291397/article/details/104475843