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
第四步:关键实现技巧
-
牌组表示:
vector<string> deck(52); // 生成方法: for(花色){ for(牌值){ deck.push_back(牌值 + " of " + 花色); } }
-
洗牌操作:
vector<string> newDeck(52); for(int i=0; i<52; i++){ newDeck[i] = deck[ shuffle[k][i] - 1 ]; // 注意-1转换 } deck = newDeck; // 更新牌组
-
输入处理技巧:
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
- 上传者