1 条题解

  • 0

    第一步:理解初始牌序(关键!)

    • 花色顺序:Clubs(梅花)→ Diamonds(方块)→ Hearts(红心)→ Spades(黑桃)
    • 牌值顺序:2-10 → Jack → Queen → King → Ace
    • 示例
      第1张:2 of Clubs
      第2张:3 of Clubs
      ...
      第52张:Ace of Spades
      

    第二步:洗牌规则解析

    • 每种洗牌法是一个置换操作(52个数字的排列)
    • 数字含义shuffle[i] = j 表示"移动第i张牌到位置j"
    • 示例
      输入 [2,1,3,4...] 表示:
        新牌组[0] = 原牌组[1]  # 注意C++是0-based索引
        新牌组[1] = 原牌组[0]
        新牌组[2] = 原牌组[2]
      

    第三步:算法流程

    graph TD
        A[生成初始牌组] --> B[读取所有洗牌法]
        B --> C{是否有新洗牌指令?}
        C -->|是| D[执行指定洗牌法]
        C -->|否| E[结束]
        D --> F[输出当前牌序]
        F --> C
    

    第四步:关键实现技巧

    1. 牌组表示

      vector<string> deck(52);
      // 生成方法:
      for(花色){
        for(牌值){
          deck.push_back(牌值 + " of " + 花色);
        }
      }
      
    2. 洗牌操作

      vector<string> newDeck(52);
      for(int i=0; i<52; i++){
        newDeck[i] = deck[ shuffle[k][i] - 1 ]; // 注意-1转换
      }
      deck = newDeck; // 更新牌组
      
    3. 输入处理技巧

      while(cin >> k){ // 自动持续读取直到EOF
        // 处理第k种洗牌
      }
      
      

    复杂度分析

    • 时间复杂度:O(52n + 52k) ≈ O(1)(因为52是常数)
    • 空间复杂度:O(52*n)(存储所有洗牌法)

    标程

    #include <iostream>
    #include <vector>
    #include <string>
    using namespace std;
    
    // 生成初始牌组
    vector<string> buildDeck() {
        string suits[] = {"Clubs", "Diamonds", "Hearts", "Spades"};
        string values[] = {"2", "3", "4", "5", "6", "7", "8", "9", "10", 
            "Jack", "Queen", "King", "Ace"};
        vector<string> deck;
        for (size_t i = 0; i < sizeof(suits)/sizeof(suits[0]); ++i) {
            for (size_t j = 0; j < sizeof(values)/sizeof(values[0]); ++j) {
                deck.push_back(values[j] + " of " + suits[i]);
            }
        }
        return deck;
    }
    
    int main() {
        int n;
        cin >> n;
        
        // 读取所有洗牌方式
        vector<vector<int> > shuffles(n, vector<int>(52));
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < 52; ++j) {
                cin >> shuffles[i][j];
            }
        }
        
        // 初始牌组
        vector<string> deck = buildDeck();
        
        // 处理每次洗牌
        int k;
        while (cin >> k) {
            vector<string> newDeck(52);
            // 执行第k种洗牌(注意题目中编号是1-based)
            for (int i = 0; i < 52; ++i) {
                newDeck[i] = deck[shuffles[k-1][i] - 1];
            }
            deck = newDeck;
            
            // 输出结果
            for (size_t i = 0; i < deck.size(); ++i) {
                cout << deck[i] << endl;
            }
            cout << endl; // 每组输出后空一行
        }
        
        return 0;
    }
    • 1

    信息

    ID
    1470
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者