【PAT A1042 】Shuffling Machine (20分)

入门模拟-简单模拟

简单模拟介绍

PAT甲乙级中入门模拟题,入门模拟题又分为简单模拟,查找元素,图形输出,日期处理,进制转换,字符串处理等等!

何为模拟题?

模拟题是一类“题目怎么说,你就怎么做的”的题目,如果实现不太麻烦可以称	之为就“简单模拟”
此类题目不涉及算法,完全根据题目描述进行代码的编写,主要考察代码能力

虽听起来可能蛮简单的,但绝不是1 + 1 = 2的题目!!!

有些题实现起来确实有小难度!

题目链接 ——【PAT A1042 】Shuffling Machine (20分)
该题来自PAT甲级题库里的一道稍微拔高一点的模拟题!!!

题目虽是英文的,但是大体意思还是可以读懂,不懂的单词或者句子也可以使用翻译软件
现在翻译工具太多啦!因此英文不是退却的借口。

题意:

For example, suppose we only have 5 cards: S3, H5, C1, D13 and J2. Given a shuffling order {4, 2, 5, 3, 1}, the result will be: J2, H5, D13, S3, C1. If we are to repeat the shuffling again, the result will be: C1, H5, S3, J2, D13.

Sample Input:
2
36 52 37 38 3 39 40 53 54 41 11 12 13 42 43 44 2 4 23 24 25 26 27 6 7 8 48 49 
50 51 9 10 14 15 16 5 17 18 19 1 20 21 22 28 29 30 31 32 33 34 35 45 46 47

Sample Output:
S7 C11 C10 C12 S1 H7 H8 H9 D8 D9 S11 S12 S13 D10 D11 D12 S3 S4 S6 S10 H1 	
H2 C13 D2 D3 D4 H6 H3 D13 J1 J2 C1 C2 C3 C4 D1 S5 H5 H11 H12 C6 C7 C8 C9 
S2 S8 S9 H10 D5 D6 D7 H4 H13 C5

本题一个洗牌程序,题目首先给定一个洗牌的序列,当然我们就可以理解成数组啦!
这个序列是由54个整数组成,数组i位置的元素应该移到a[i]位置上(假定设定的数组为a数组,那么j就是等于a[i]啦)

S3, H5, C1, D13 J2.我们假设五个对应的序号是 1 2 3 4 5
S3(1), H5(2), C1(3), D13(4), J2(5).

给定的洗牌序列:{4, 2, 5, 3, 1} --> a[5] = {4, 2, 5,3,1}
即是 第 1位置的元素移到 第4 位置,。。。。。。第3位置的元素移到第5位置。。。。。,即第i位置的元素移到a[i]位置上

第一次洗牌后的顺序是 J2(5), H5(2), D13(4), S3(1), C1(3).

接下来可以自己在纸上尝试第二次洗牌,看与结果是否相同?

有人说我知道是如何洗牌的,但是我不知道如何实现的呀?

我们现在来看上面的样例的输入输出,我们先假设一个元素即可

S7 是7号元素,首先我们在洗牌序列中找到第7号位置的值40,即表示S7 移到40号位置
在第二轮洗牌中我们找40号位置的值1即表示S7移到1号位置。结果证明1号位置输出S7
其他的元素的移动同理

题解:

既然7号位置移到40号位置,为此我们设置一个数组b 
即b[ a[i] ] =  i;即在40号位置为 7号元素 b[40] = 7;但是如何表示1号位置输出7号元素呢?
(结合短例子和	输出输入样例,并画图测试)

我们很容易想到再开一个数组c用来存放刚刚的b数组值  
那么第二次洗牌 即 b[ a[i] ] = c[i];   即在1号位置为7号元素
( b[a[40] ] = b[1] )     =   (c[40] = b[40] = 7)

每洗完一次都可以赋值给c数组,洗k次最后通过c数组来进行输出

C++代码实现:

#include <iostream>
using namespace std;
void Print(int t)//输出方式有很多,这不是重点,重点是我们根据位置编号来输出的
{
    if (t <= 13) cout << "S" << t;
    else if (t <= 26)
    {
        if (t == 26) cout << "H13" ;
        else cout << "H" << t % 13 ;
    }
    else if (t <= 39)
    {
        if (t == 39) cout << "C13" ;
        else cout << "C" << t % 13 ;
    }
    else if (t <= 52)
    {
        if (t == 52) cout << "D13";
        else cout << "D" << t % 13 ;
    }
    else  cout << "J" << t % 52 ;
}

int main()
{
    int a[56], n;
    int b[56], c[56];
    cin >> n;
    for (int i = 1; i <= 54;i++)
    {
        cin >> a[i];
    }
    for (int k = 0; k < n; k++) {
        if (k == 0)
        {
            for (int i = 1; i <= 54; i++)
                b[a[i]] = i;//第一次洗牌获取位置编号
        }
       else {
        for (int i = 1; i <= 54; i++)
                b[a[i]] = c[i];//二三次~多次洗牌的关键代码
       }

        for (int j = 1; j <= 54; j++)
        c[j] = b[j];//每次将b数组赋值给c数组
    }
    
    for (int i = 1; i <= 54; i++)//最后通过c数组来输出
    {
        Print(c[i]);
        if (i != 54) cout << " ";
        else cout << endl;
    }
    return 0;
}

©️2020 CSDN 皮肤主题: 岁月 设计师:pinMode 返回首页