PAT (Advanced Level) Practice 1042 Shuffling Machine (20 分) 凌宸1642
阅读原文时间:2023年07月09日阅读:3

题目描述:

Shuffling is a procedure used to randomize a deck of playing cards. Because standard shuffling techniques are seen as weak, and in order to avoid "inside jobs" where employees collaborate with gamblers by performing inadequate shuffles, many casinos employ automatic shuffling machines. Your task is to simulate a shuffling machine.

The machine shuffles a deck of 54 cards according to a given random order and repeats for a given number of times. It is assumed that the initial status of a card deck is in the following order:

S1, S2, ..., S13,
H1, H2, ..., H13,
C1, C2, ..., C13,
D1, D2, ..., D13,
J1, J2

where "S" stands for "Spade", "H" for "Heart", "C" for "Club", "D" for "Diamond", and "J" for "Joker". A given order is a permutation of distinct integers in [1, 54]. If the number at the i-th position is j, it means to move the card from position i to position j. 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.

译:洗牌是一种用来随机化一副扑克牌的程序。因为标准的洗牌技术被认为是软弱的,而且为了避免员工通过不充分的洗牌与赌客合作的“内部工作”,许多赌场雇用了自动洗牌机。你的任务是模拟洗牌机。

机器根据给定的随机顺序洗牌54张,并重复给定的次数。假设一张牌组的初始状态按以下顺序排列:

S1, S2, ..., S13,
H1, H2, ..., H13,
C1, C2, ..., C13,
D1, D2, ..., D13,
J1, J2

“S”代表 黑桃,“H”代表 红心 ,“C”代表 梅花 ,“D”代表 方块,“J”代表 王 。给定的顺序是[1 , 54]中不同整数的排列。如果第 i 个位置的数字是 j ,则意味着将牌从第 i 个位置移动到第 j 个位置。例如,假设我们只有 5 张牌 : S3, H5 , C1 , D13 和 J2。给定洗牌顺序{ 4 , 2 , 5 , 3 , 1 } ,结果为 : J2 , H5 , D13 , S3 , C1。如果我们再次洗牌,结果将是:C1, H5, S3 , J2 , D13。


Input Specification (输入说明):

Each input file contains one test case. For each case, the first line contains a positive integer K (≤20) which is the number of repeat times. Then the next line contains the given order. All the numbers in a line are separated by a space.

译:每个输入文件包含一个测试用例,每个用例在第一行中包含一个正整数 K (≤ 20 ) , 表示重复次数。所有的数字被一个空格分隔。


Output Specification (输出说明):

For each test case, print the shuffling results in one line. All the cards are separated by a space, and there must be no extra space at the end of the line.

译:对于每个测试用例,在一个行中输出洗牌后的顺序。所有的牌都被空格隔开,并且行末没有多与的空格。


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


The Idea:

首先看最后一题的题目文字数量确实有被下到,但是仔细去理解,其实就是相当于给你一个数组,然后按照数字的初始的每个元素的大小将其放到对应的位置上去,然后重复操作 k 次,得到的位置就是原先牌需要存放的位置。使用 map 来存储数字到牌的映射,使用 string 数组存储最后的洗好牌的数学,采用 int 型数组存储输入的顺序。


The Codes:

#include<bits/stdc++.h>
using namespace std;
int num[55] , n ;
map<int , string > mp ;
string ans[55] ;
void init(){
    for(int i = 1 ; i <= 54 ; i ++){
        if( i <= 13) mp[i] = ("S" + to_string(i)) ; // 黑桃牌面
        else if(i <= 26) mp[i] = ("H" + to_string(i - 13)) ; // 红心牌面
        else if(i <= 39) mp[i] = ("C" + to_string(i - 26)) ; // 梅花牌面
        else if (i <=52) mp[i] = ("D" + to_string(i - 39 )); // 方块牌面
        else if(i == 53) mp[i] = "J1" ; // 小王
        else mp[i] = "J2" ; // 大王
    }
}
int main(){
    init() ; // 完成数字到牌面的初始化映射
    scanf("%d" , &n) ;
    for(int i = 1 ; i <= 54 ; i ++) scanf("%d" ,&num[i]) ; // 存储输入的顺序
    for(int i = 1 ; i <= 54 ; i ++){
        int temp  = num[i] ; // 获得当前数字
        for(int j = 0 ; j < n ; j ++) temp = num[temp] ; // temp 中存储第 j 次洗牌后的位置
        ans[temp] = mp[num[i]] ; // 在该位置上存储 原先数字对应的 牌面
    }
    // 输出牌面 , 采用 printf 输出字符串时 需要用 c_str() 进行转换
    for(int i = 1 ; i <= 54 ; i ++) printf("%s%c",ans[i].c_str() , (i==54)?'\n':' ');
    return 0;
}