1 条题解

  • 0
    @ 2025-8-24 21:17:38

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Bert2012
    **

    搬运于2025-08-24 21:17:37,当前版本为作者最后更新于2025-04-30 19:17:33,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题目跳转站:

    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;
    }
    
    • 1

    信息

    ID
    11563
    时间
    1000ms
    内存
    512MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者