演算法題 - Shuffling Machine

云茗發表於2024-03-10
Introduction:
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.
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.
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

首先理解一下題目:

我們有一副有序的撲克牌(int[54]),需要拿到一組指令集(int[54]),和指令集執行次數(int),然後按照指令集交換卡牌的位置,最後輸出卡牌的位置

輸入:

1個整數,1個長度為54的陣列

過程:

  1. 生成一個長度為54的有序陣列,資料從1-54按升序排列
  2. 然後進行若干次迴圈,交換卡牌的位置

輸出:

列印出卡牌的“花色”和“數字”

額外想法:

  • 把卡牌抽象成1-54,最後用字典來輸出。這樣可以簡化卡牌的生成,專心實現卡牌交換
  • 把卡牌數54抽象到一個固定變數MAXSIZE,增加複用的可能

抽象實現:

#include <stdio.h>
const int MAXSIZE = 54;

int initOrders(int orders[]);
int initCards(int cards[]);
int exchangeCards(int cards[], int orders[], int repeatCount);
void outputWithDictionary(int output);

int main()
{
    int cards[MAXSIZE];
    int orders[MAXSIZE];
    int repeatCount = 0;

    // Input count and orders
    scanf("%d", &repeatCount);
    initOrders(orders);

    // Initialize cards
    initCards(cards);

    // Process
    exchangeCards(cards, orders, repeatCount);

    // Output cards
    for (int i = 0; i < MAXSIZE; i++)
    {
        int output = cards[i];
        outputWithDictionary(output);
        if (i < MAXSIZE - 1)
        {
            printf(" ");
        }
    }
}

然後是過程的具體實現

讀取指令:for迴圈

點選檢視程式碼
int initOrders(int orders[])
{
    for (int i = 0; i < MAXSIZE; i++)
    {
        scanf("%d", &orders[i]);
    }
    // for (int i = 0; i < MAXSIZE; i++)
    // {
    //     printf("%d ", orders[i]);
    // }
    // printf("\n");
    return 0;
}

初始化卡牌: for迴圈

點選檢視程式碼
int initCards(int cards[])
{
    for (int i = 0; i < MAXSIZE; i++)
    {
        cards[i] = i + 1;
    }
    // for (int i = 0; i < MAXSIZE; i++)
    // {
    //     printf("%d ", cards[i]);
    // }
    // printf("\n");
    return 0;
}

交換卡牌:

  • 使用了一箇中介的陣列,儲存卡牌按照指令修改後的位置。然後用for迴圈依次掃描填入後,再將臨時陣列的內容放回卡牌陣列中。複雜度O(2N)=>O(N)
點選檢視程式碼

int exchangeCards(int cards[], int orders[], int repeatCount)
{
    int temps[MAXSIZE] = {0};
    for (int i = 0; i < repeatCount; i++)
    {
        for (int j = 0; j < MAXSIZE; j++)
        {
            temps[orders[j] - 1] = cards[j];
        }
        for (int j = 0; j < MAXSIZE; j++)
        {
            cards[j] = temps[j];
        }
    }
    return 0;
}

輸出字典:

  • 每13張更換一次色號——首字母,大小王各1張(J1,J2)。用If判斷簡單實現,switch也行。
點選檢視程式碼
void outputWithDictionary(int output)
{
    if (output <= 13)
    {
        printf("S%d", output);
    }
    else if (output <= 26)
    {
        printf("H%d", output - 13);
    }
    else if (output <= 39)
    {
        printf("C%d", output - 26);
    }
    else if (output <= 52)
    {
        printf("D%d", output - 39);
    }
    else if (output <= 54)
    {
        printf("J%d", output - 52);
    }
}

完整程式碼

#include <stdio.h>
const int MAXSIZE = 54;

int initOrders(int orders[]);
int initCards(int cards[]);
int exchangeCards(int cards[], int orders[], int repeatCount);
void outputWithDictionary(int output);

int main()
{
    int cards[MAXSIZE];
    int orders[MAXSIZE];
    int repeatCount = 0;

    // Input count and orders
    scanf("%d", &repeatCount);
    initOrders(orders);

    // Initialize cards
    initCards(cards);

    // Process
    exchangeCards(cards, orders, repeatCount);

    // Output cards
    for (int i = 0; i < MAXSIZE; i++)
    {
        int output = cards[i];
        outputWithDictionary(output);
        if (i < MAXSIZE - 1)
        {
            printf(" ");
        }
    }
}

int initOrders(int orders[])
{
    for (int i = 0; i < MAXSIZE; i++)
    {
        scanf("%d", &orders[i]);
    }
    // for (int i = 0; i < MAXSIZE; i++)
    // {
    //     printf("%d ", orders[i]);
    // }
    // printf("\n");
    return 0;
}

int initCards(int cards[])
{
    for (int i = 0; i < MAXSIZE; i++)
    {
        cards[i] = i + 1;
    }
    // for (int i = 0; i < MAXSIZE; i++)
    // {
    //     printf("%d ", cards[i]);
    // }
    // printf("\n");
    return 0;
}

int exchangeCards(int cards[], int orders[], int repeatCount)
{
    int temps[MAXSIZE] = {0};
    for (int i = 0; i < repeatCount; i++)
    {
        for (int j = 0; j < MAXSIZE; j++)
        {
            temps[orders[j] - 1] = cards[j];
        }
        for (int j = 0; j < MAXSIZE; j++)
        {
            cards[j] = temps[j];
        }
    }
    return 0;
}

void outputWithDictionary(int output)
{
    if (output <= 13)
    {
        printf("S%d", output);
    }
    else if (output <= 26)
    {
        printf("H%d", output - 13);
    }
    else if (output <= 39)
    {
        printf("C%d", output - 26);
    }
    else if (output <= 52)
    {
        printf("D%d", output - 39);
    }
    else if (output <= 54)
    {
        printf("J%d", output - 52);
    }
}

相關文章