题解:B4180 [厦门小学生 C++ 2024] 乌龟对对碰
题目跳转站:
B4180 [厦门小学生 C++ 2024] 乌龟对对碰
代码解析:
纯模拟题!!!
函数:
p1 函数: 判断是否满足条件 1,通过统计九宫格中每种颜色乌龟数量,找出成对的乌龟并移除,返回拿走的乌龟对数(即赠送盲盒数)。
代码:
int p1() {
// 记录生成的新字符数量
int n = 0;
// 初始化计数数组
memset(c, 0, sizeof(c));
// 统计九宫格中每个数字出现的次数
for (int x = 1; x <= 3; x++) {
for (int y = 1; y <= 3; y++) {
if (g[x][y] != -1) {
c[g[x][y]]++;
}
}
}
// 遍历每个数字
for (int x = 0; x < 10; x++) {
if (c[x] < 2) continue;
// 计算该数字可组成的对数
int t = c[x] / 2 * 2;
// 累加生成的新字符数量
n += c[x] / 2;
// 更新该数字剩余的数量
c[x] %= 2;
// 从九宫格中移除组成对的数字
for (int y = 1; y <= 3; y++) {
for (int z = 1; z <= 3; z++) {
if (g[y][z] == x) {
g[y][z] = -1;
if (--t == 0) break;
}
}
if (t < 1) break;
}
}
return n;
}
p2 函数: 判断是否满足条件 2,在满足条件 1 的基础上,检查按条件 1 操作后 9 宫格是否为空,若为空返回赠送盲盒数 8,否则返回 0。
代码:
// 处理九宫格全空的特殊情况的函数
int p2() {
// 标记九宫格是否全空
bool e = true;
for (int x = 1; x <= 3; x++) {
if (g[x][1] != -1 || g[x][2] != -1 || g[x][3] != -1) {
e = false;
}
}
// 如果满足特定条件且九宫格全空
if (f && e) {
return 8;
}
return 0;
}
p3 函数: 判断是否满足条件 3,检查 9 宫格是否全满且乌龟颜色各不相同,若满足返回赠送盲盒数 10,否则返回 0。
代码:
// 处理九宫格无重复数字的特殊情况的函数
int p3() {
// 标记九宫格是否有空位
bool e = false;
for (int x = 1; x <= 3; x++) {
for (int y = 1; y <= 3; y++) {
if (g[x][y] == -1) {
e = true;
}
}
}
// 如果有空位,直接返回 0
if (e) return 0;
// 重新初始化计数数组
memset(c, 0, sizeof(c));
// 统计九宫格中每个数字出现的次数
for (int x = 1; x <= 3; x++) {
for (int y = 1; y <= 3; y++) {
if (g[x][y] != -1) {
c[g[x][y]]++;
}
}
}
// 标记九宫格中的数字是否都唯一
bool u = true;
for (int x = 0; x < 10; x++) {
if (c[x] > 1) {
u = false;
break;
}
}
// 如果数字都唯一
if (u) {
// 清空九宫格
for (int x = 1; x <= 3; x++) {
for (int y = 1; y <= 3; y++) {
g[x][y] = -1;
}
}
return 10;
}
return 0;
}
主流程: 读取盲盒序列和购买的盲盒数量,将购买的盲盒存入 w 。进入循环,不断将未打开的盲盒放入 9 宫格,检查三个条件。若满足条件,根据条件获得赠送盲盒并更新 w 和最终获得乌龟总数 a 。若某一轮没有获得赠送盲盒,说明游戏结束,计算并输出最终获得的乌龟总数(购买的盲盒数量 b 加上赠送的乌龟数量 a )。
代码:
int main() {
// 输入字符串
cin >> s;
// 输入初始购买的字符数量
scanf("%d", &b);
// 初始购买字符添加到可用字符中
for (int x = 0; x < b; x++) {
w += s[i++];
}
while (1) {
// 标记本轮是否有变化
bool ch = false;
// 可用字符的索引
int j = -1;
// 可用字符的长度
int l = w.size();
// 填充九宫格
for (int x = 1; x <= 3; x++) {
for (int y = 1; y <= 3; y++) {
if (g[x][y] == -1 && j + 1 < l) {
g[x][y] = w[++j] - '0';
}
}
}
// 移除已使用的可用字符
w.erase(0, j + 1);
// 调用 p1 函数处理相同数字对
int r = p1();
if (r) {
f = true;
ch = true;
// 生成新的可用字符
for (int x = 1; x <= r; x++) {
w += s[i++];
}
// 累加结果
a += r;
}
// 调用 p2 函数处理全空情况
r = p2();
if (r) {
ch = true;
// 生成新的可用字符
for (int x = 1; x <= r; x++) {
w += s[i++];
}
// 累加结果
a += r;
}
// 调用 p3 函数处理无重复数字情况
r = p3();
if (r) {
ch = true;
// 生成新的可用字符
for (int x = 1; x <= r; x++) {
w += s[i++];
}
// 累加结果
a += r;
}
// 如果本轮没有变化,退出循环
if (!ch) break;
}
// 输出最终结果
printf("%d", a + b);
return 0;
}
最终代码:
#include <bits/stdc++.h>
using namespace std;
// 存储输入的字符串
string s;
// 存储当前可用的字符
string w;
// 初始购买的字符数量
int b;
// 当前处理到输入字符串的索引
int i;
// 记录每个数字出现的次数
int c[11];
// 最终结果
int a;
// 3x3 的九宫格数组,初始值为 -1 表示空位
int g[4][4] = {
{-1, -1, -1, -1},
{-1, -1, -1, -1},
{-1, -1, -1, -1},
{-1, -1, -1, -1}
};
// 标记是否满足特定条件
bool f;
// 处理九宫格中相同数字对的函数
int p1() {
// 记录生成的新字符数量
int n = 0;
// 初始化计数数组
memset(c, 0, sizeof(c));
// 统计九宫格中每个数字出现的次数
for (int x = 1; x <= 3; x++) {
for (int y = 1; y <= 3; y++) {
if (g[x][y] != -1) {
c[g[x][y]]++;
}
}
}
// 遍历每个数字
for (int x = 0; x < 10; x++) {
if (c[x] < 2) continue;
// 计算该数字可组成的对数
int t = c[x] / 2 * 2;
// 累加生成的新字符数量
n += c[x] / 2;
// 更新该数字剩余的数量
c[x] %= 2;
// 从九宫格中移除组成对的数字
for (int y = 1; y <= 3; y++) {
for (int z = 1; z <= 3; z++) {
if (g[y][z] == x) {
g[y][z] = -1;
if (--t == 0) break;
}
}
if (t < 1) break;
}
}
return n;
}
// 处理九宫格全空的特殊情况的函数
int p2() {
// 标记九宫格是否全空
bool e = true;
for (int x = 1; x <= 3; x++) {
if (g[x][1] != -1 || g[x][2] != -1 || g[x][3] != -1) {
e = false;
}
}
// 如果满足特定条件且九宫格全空
if (f && e) {
return 8;
}
return 0;
}
// 处理九宫格无重复数字的特殊情况的函数
int p3() {
// 标记九宫格是否有空位
bool e = false;
for (int x = 1; x <= 3; x++) {
for (int y = 1; y <= 3; y++) {
if (g[x][y] == -1) {
e = true;
}
}
}
// 如果有空位,直接返回 0
if (e) return 0;
// 重新初始化计数数组
memset(c, 0, sizeof(c));
// 统计九宫格中每个数字出现的次数
for (int x = 1; x <= 3; x++) {
for (int y = 1; y <= 3; y++) {
if (g[x][y] != -1) {
c[g[x][y]]++;
}
}
}
// 标记九宫格中的数字是否都唯一
bool u = true;
for (int x = 0; x < 10; x++) {
if (c[x] > 1) {
u = false;
break;
}
}
// 如果数字都唯一
if (u) {
// 清空九宫格
for (int x = 1; x <= 3; x++) {
for (int y = 1; y <= 3; y++) {
g[x][y] = -1;
}
}
return 10;
}
return 0;
}
int main() {
// 输入字符串
cin >> s;
// 输入初始购买的字符数量
scanf("%d", &b);
// 初始购买字符添加到可用字符中
for (int x = 0; x < b; x++) {
w += s[i++];
}
while (1) {
// 标记本轮是否有变化
bool ch = false;
// 可用字符的索引
int j = -1;
// 可用字符的长度
int l = w.size();
// 填充九宫格
for (int x = 1; x <= 3; x++) {
for (int y = 1; y <= 3; y++) {
if (g[x][y] == -1 && j + 1 < l) {
g[x][y] = w[++j] - '0';
}
}
}
// 移除已使用的可用字符
w.erase(0, j + 1);
// 调用 p1 函数处理相同数字对
int r = p1();
if (r) {
f = true;
ch = true;
// 生成新的可用字符
for (int x = 1; x <= r; x++) {
w += s[i++];
}
// 累加结果
a += r;
}
// 调用 p2 函数处理全空情况
r = p2();
if (r) {
ch = true;
// 生成新的可用字符
for (int x = 1; x <= r; x++) {
w += s[i++];
}
// 累加结果
a += r;
}
// 调用 p3 函数处理无重复数字情况
r = p3();
if (r) {
ch = true;
// 生成新的可用字符
for (int x = 1; x <= r; x++) {
w += s[i++];
}
// 累加结果
a += r;
}
// 如果本轮没有变化,退出循环
if (!ch) break;
}
// 输出最终结果
printf("%d", a + b);
return 0;
}