C++ 实现计算斗地主手牌最少出牌次数:代码、规则与复杂度全解析
以下是一个用 C++ 实现的解决方案,用于计算每组手牌最少需要多少次出牌可以打光。 ```cpp #include <iostream> #include <vector> #include <algorithm> // 定义牌的结构体 struct Card { int num; // 牌的数码 int suit; // 牌的花色 Card(int n, int s) : num(n), suit(s) {} }; // 比较函数,用于对牌进行排序 bool compareCards(const Card& a, const Card& b) { if (a.num != b.num) { if (a.num == 0) return false; // 大小王放最后 if (b.num == 0) return true; if (a.num == 2) return false; // 2 放较后 if (b.num == 2) return true; if (a.num == 1) return false; // A 放较后 if (b.num == 1) return true; return a.num < b.num; } return a.suit < b.suit; } // 计算最少出牌次数 int minMovesToClear(std::vector<Card>& hand) { std::sort(hand.begin(), hand.end(), compareCards); int moves = 0; int i = 0; while (i < hand.size()) { // 处理大小王 if (hand[i].num == 0) { if (i + 1 < hand.size() && hand[i + 1].num == 0) { i += 2; // 大小王一起出 } else { i++; // 单出小王或大王 } moves++; continue; } // 寻找连续相同数码的牌 int j = i; while (j < hand.size() && hand[j].num == hand[i].num) { j++; } moves++; // 出这组相同数码的牌 i = j; } return moves; } int main() { int T, n; std::cin >> T >> n; for (int t = 0; t < T; t++) { std::vector<Card> hand; for (int i = 0; i < n; i++) { int a, b; std::cin >> a >> b; hand.emplace_back(a, b); } int result = minMovesToClear(hand); std::cout << result << std::endl; } return 0; } ``` 代码说明: 1. 结构体 `Card`:用于存储每张牌的数码和花色。 2. 比较函数 `compareCards`:对牌进行排序,大小王放2 和 A 也相对靠后,其余按数码从小到大排序。 3. 函数 `minMovesToClear`: - 首先对牌进行排序。 - 遍历手牌,处理大小王的情况,如果有大小王可以一起出,否则单出。 - 对于其他牌,寻找连续相同数码的牌,将其作为一组出牌。 4. 主函数 `main`: - 读取输入的手牌组数 `T` 和每组手牌的张数 `n`。 - 对于每组手牌,读取每张牌的信息并存储在 `hand` 向量中。 - 调用 `minMovesToClear` 函数计算最少出牌次数并输出结果。 复杂度分析: - 时间复杂度:排序的时间复杂度为 $O(n log n)$,遍历手牌的时间复杂度为 $O(n)$,因此总的时间复杂度为 $O(n log n)$。 - 空间复杂度:主要用于存储手牌,空间复杂度为 $O(n)$。 ######[AI问答 | 894点数解答 | 2026-01-24 22:37:01]
- Python 实现球类:精准计算半径、表面积与体积,附输入验证与异常处理!(阿里通义 | 261点数解答 | 2024-11-28 21:19:39)350
- 游戏技能代码深度剖析:潜在问题、改进方案与处理要点(字节豆包 | 1426点数解答 | 2025-10-16 15:31:36)114
- C++求解序列或与运算和差值:避O(nq)复杂度及数据处理要点(字节豆包 | 534点数解答 | 2025-10-17 20:05:07)64
- Golang开发:解析JSON数据时数值默认类型及示例解析(百度文心 | 393点数解答 | 2023-11-09 18:13:06)283
- SQL Working Areas Sizing: Manual vs. Automatic Policy - A Comprehensive Analysis(阿里通义 | 530点数解答 | 2024-05-13 10:55:58)310
- 51 单片机:定时器 0 实现 8 个 LED 循环点亮,附代码及优化建议(字节豆包 | 1193点数解答 | 2024-12-27 15:10:29)322
- 用 JS 实现网页猜数字游戏:1 - 100 随机数等你挑战!(百度文心 | 653点数解答 | 2025-03-26 14:39:33)241
- JS实现猜数字游戏:弹窗输入,1 - 100随机挑战,教你轻松上手!(百度文心 | 646点数解答 | 2025-03-26 14:49:43)201
- 融合道德感机制:女性NPC规则全面升级(字节豆包 | 1489点数解答 | 2025-06-20 20:06:34)159
- C++ 解决老师奖励同学铅笔数量问题:最少奖励方案揭秘(字节豆包 | 724点数解答 | 2025-12-06 20:58:32)47
- 用 JS 中 for 循环实现 1 到 100 相加并输出结果到页面的完整代码 ( | 240点数解答 | 2024-05-20 22:11:29)471
- 用 JS 的 while 循环实现 1 到 100 相加并输出到页面的代码揭秘( | 47点数解答 | 2024-05-20 22:16:48)361