1 条题解
-
0
解题思路:
本题模拟Snap卡牌游戏,核心在于正确处理牌堆的动态变化及Snap时的牌堆转移逻辑,同时严格遵循输出格式和终止条件。
关键步骤:
-
数据结构选择:
- 使用队列()模拟玩家当前的面朝下牌堆,保证从顶部依次出牌。
- 使用向量()临时存储每轮打出的牌,便于处理Snap时的牌堆合并。
-
游戏流程模拟:
- 出牌阶段:每轮双方各出一张牌到临时向量。若牌相同,触发Snap判断。
- Snap处理:根据随机结果决定胜者,将对方的临时牌堆合并到己方队列顶部,并清空对方临时牌堆。
- 牌堆翻转:当队列为空时,将临时向量中的牌倒序压回队列,模拟牌堆翻转逻辑。
-
终止条件判断:
- 轮数限制:最多进行轮,超时输出“Keeps going and going ...”。
- 胜负判定:当任一玩家的队列和临时向量总牌数等于初始总牌数时,该玩家获胜。
-
输出细节处理:
- Snap发生时,按题目要求输出对应玩家的临时牌堆(需逆序打印,因向量存储顺序为从顶到底)。
- 使用模拟随机决策,代表Jane先喊,代表John先喊。
代码解释:
- 初始化:读取Jane和John的初始牌堆,存入队列和。
- 主循环:
- 每轮从队列头部取牌存入临时向量和。
- 若牌相同,根据随机结果转移牌堆并输出对应信息。
- 队列空时,将临时向量倒序压回队列(模拟牌堆翻转)。
- 终止判断:检查轮数或牌堆归属,输出结果。
C++实现:
#include <queue> #include <cstdio> #include <vector> #include <cstring> #include <algorithm> using namespace std; int main() { char s1[1000], s2[1000]; while (~scanf("%s%s", s1, s2)) { // 读取输入 int len = strlen(s1); queue<char> p, q; // Jane和John的当前牌堆 vector<char> vp, vq; // 临时存放打出的牌 // 初始化队列 for (int i = 0; s1[i]; i++) p.push(s1[i]); for (int i = 0; s2[i]; i++) q.push(s2[i]); int cnt = 0; // 轮数计数器 bool ongoing = true; // 游戏进行标志 while (cnt < 1000 && ongoing) { // 出牌阶段 if (p.empty() || q.empty()) break; // 牌堆为空则游戏结束 vp.push_back(p.front()); p.pop(); vq.push_back(q.front()); q.pop(); cnt++; // 检查Snap if (!vp.empty() && !vq.empty() && vp.back() == vq.back()) { int t = rand() / 99 % 2; // 随机决定胜者 if (t == 0) { // Jane获胜 // 转移John的牌到Jane的队列 for (char c : vq) p.push(c); vq.clear(); // 输出Jane的牌堆(逆序) printf("Snap! for Jane: "); for (auto it = vp.rbegin(); it != vp.rend(); ++it) printf("%c", *it); puts(""); } else { // John获胜 // 转移Jane的牌到John的队列 for (char c : vp) q.push(c); vp.clear(); // 输出John的牌堆(逆序) printf("Snap! for John: "); for (auto it = vq.rbegin(); it != vq.rend(); ++it) printf("%c", *it); puts(""); } // 清空临时向量 vp.clear(); vq.clear(); } // 牌堆翻转逻辑 if (p.empty()) { for (int i = vp.size()-1; i >= 0; i--) p.push(vp[i]); vp.clear(); } if (q.empty()) { for (int i = vq.size()-1; i >= 0; i--) q.push(vq[i]); vq.clear(); } // 检查胜负 if (p.size() + vp.size() == 2 * len) { ongoing = false; puts("Jane wins."); } if (q.size() + vq.size() == 2 * len) { ongoing = false; puts("John wins."); } } // 超时未结束 if (cnt == 1000 && ongoing) puts("Keeps going and going ..."); } return 0; }
-
- 1
信息
- ID
- 1590
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 7
- 已通过
- 1
- 上传者