跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

第十六届蓝桥杯省赛 C/C++ 大学 A 组真题解析

综述由AI生成解析了第十六届蓝桥杯省赛 C/C++ 大学 A 组的前两道真题。A 题要求寻找第 2025 个质数,采用试除法枚举,结果为 17627。B 题为 6x6 黑白棋填充问题,需满足行列数量相等、无三连及行列唯一性约束,通过深度优先搜索(DFS)配合剪枝策略求解。提供了完整的 C++ 实现代码及逻辑说明。

王者发布于 2026/3/30更新于 2026/5/2431 浏览
第十六届蓝桥杯省赛 C/C++ 大学 A 组真题解析

题目一:寻找质数

题目描述

本题的目标是枚举质数并计数,直到数到第 2025 个。由于 2025 不算太大,第 2025 个质数大约在 17000~18000 之间,完全可以在合理时间内通过简单枚举得到。

解题步骤

从 2 开始遍历每个整数,判断它是否是质数。质数判断采用试除法:对于一个数 n,只需检查从 2 到√n 的所有整数是否能整除 n。若存在能整除的数,则 n 不是质数;否则是质数。每找到一个质数,计数器加 1。当计数器达到 2025 时,输出当前的质数并结束。 优化点:除了 2 以外,偶数不可能是质数,因此可以跳过偶数判断(直接步进 2)。

C++ 参考代码

#include <iostream>
#include <cmath>
using namespace std;

// 判断一个整数是否为质数
bool isPrime(int n) {
    if (n < 2) return false;
    if (n == 2) return true;
    if (n % 2 == 0) return false; // 偶数直接排除
    int limit = sqrt(n); // 只需检查到平方根
    for (int i = 3; i <= limit; i += 2) { // 只检查奇数因子
        if (n % i == 0) return false;
    }
    return true;
}

int main {
     count = ; 
     num = ; 
     () {
         ((num)) {
            count++;
             (count == ) {
                cout << num << endl;
                ;
            }
        }
        num++;
    }
     ;
}
()
int
0
// 已找到的质数个数
int
2
// 从 2 开始检查
while
true
if
isPrime
if
2025
break
return
0

运行结果

在本地运行上述代码,最终输出的数字即为第 2025 个质数。该数为:17627。

题目二:黑白棋

题目回顾与核心规则

在一个 6x6 的棋盘上,已有部分格子填有黑色 (1) 或白色 (0) 棋子,需要填满所有空格,并满足以下规则:

  1. 数量相等:每一行和每一列中,黑棋和白棋的数量必须相等(即各有 3 个)。
  2. 无三连:在任何一行或一列中,不能有超过两个相同颜色的棋子连续排列(即禁止出现'111'或'000')。
  3. 行列唯一:每一行的排列方式必须是唯一的(不能与其他任何行相同);每一列的排列方式也必须是唯一的(不能与其他任何列相同)。但行与列之间可以相同。

核心解题思路:深度优先搜索(DFS)+ 剪枝

程序的核心思想是深度优先搜索(DFS),逐个格子地去尝试填入黑棋 (1) 或白棋 (0)。必须在搜索过程中进行严格的剪枝,提前排除那些不可能满足规则的分支。 主要剪枝策略:

  1. 数量限制:在放置一个棋子前,检查其所在行和列中,该颜色棋子数量是否已达到 3 个。如果已达到,就不能再放。
  2. 无三连限制:在放置一个棋子后,立即检查它是否与其左边两个(或上边两个)棋子构成了连续三个相同颜色。如果构成了,这个分支就是无效的,必须回退。
  3. 行列唯一性剪枝:每当填完一整行或一整列时,立即检查该行(或列)的排列是否与之前已完成的任何一行(或列)重复。如果重复,则剪枝。

C++ 完整源码

#include <bits/stdc++.h>
using namespace std;

// 初始化棋盘,-1 表示空格
int grid[6][6] = {
    { 1, 0, 1, 0,-1,-1},
    {-1,-1,-1, 0,-1,-1},
    {-1,-1,-1, 1, 0, 0},
    {-1,-1,-1,-1,-1,-1},
    {-1,-1, 1,-1,-1, 1},
    {-1, 0,-1,-1, 1,-1}
};

// 用于记录当前每行和每列中黑棋 (1) 和白棋 (0) 的数量
int black_row[6] = {0}, black_col[6] = {0};
int white_row[6] = {0}, white_col[6] = {0};

// 用于记录已经出现过的行排列和列排列,以实现'行列唯一性'的剪枝
unordered_set<string> vis_row, vis_col;
string ans; // 存储最终的答案字符串

// 函数:在搜索结束时,对整个棋盘进行一次最终检查
int check() {
    unordered_set<string> r, c;
    // 检查所有行是否唯一
    for (int i = 0; i < 6; i++) {
        string rr = "";
        for (int j = 0; j < 6; j++) rr += to_string(grid[i][j]);
        if (r.count(rr)) return 0; // 发现重复行,无效
        r.insert(rr);
    }
    // 检查所有列是否唯一
    for (int i = 0; i < 6; i++) {
        string cc = "";
        for (int j = 0; j < 6; j++) cc += to_string(grid[j][i]);
        if (c.count(cc)) return 0; // 发现重复列,无效
        c.insert(cc);
    }
    return 1; // 所有检查通过
}

// 核心:深度优先搜索函数,pos 表示当前正在处理的格子编号(从 0 到 35)
int solve(int pos) {
    // 如果所有格子都处理完了,进行最终检查
    if (pos == 36) {
        if (check()) {
            ans = "";
            for (int i = 0; i < 6; i++)
                for (int j = 0; j < 6; j++) ans += to_string(grid[i][j]);
            return 1; // 找到答案,返回 1
        }
        return 0;
    }

    int row = pos / 6; // 计算当前格子所在行
    int col = pos % 6; // 计算当前格子所在列

    // 如果当前格子已经有棋子(非空格),则直接跳过,处理下一个格子
    if (grid[row][col] != -1) return solve(pos + 1);

    // 尝试在当前空格放入两种颜色的棋子:val = 0 (白棋) 或 1 (黑棋)
    for (int val = 0; val <= 1; val++) {
        // 剪枝 1:检查行和列中该颜色的数量是否已达上限(3 个)
        if (!val) { // 尝试放白棋
            if (white_row[row] >= 3 || white_col[col] >= 3) continue;
        } else { // 尝试放黑棋
            if (black_row[row] >= 3 || black_col[col] >= 3) continue;
        }

        // 剪枝 2:检查是否会形成横向或纵向的三个连续相同棋子
        // 横向检查:当前格子的左边两个是否和当前尝试的 val 相同
        if (col >= 2 && grid[row][col - 2] == val && grid[row][col - 1] == val) continue;
        // 纵向检查:当前格子的上边两个是否和当前尝试的 val 相同
        if (row >= 2 && grid[row - 2][col] == val && grid[row - 1][col] == val) continue;

        // --- 执行放置操作,并更新相关计数 ---
        grid[row][col] = val;
        if (val) {
            black_row[row]++;
            black_col[col]++;
        } else {
            white_row[row]++;
            white_col[col]++;
        }

        // --- 剪枝 3:如果当前放完了一整行或一整列,检查其唯一性 ---
        int flag = 1; // 标记是否通过唯一性检查
        string rowstr = "", colstr = "";
        int full_row = (col == 5); // 是否刚填完一行
        int full_col = (row == 5); // 是否刚填完一列

        if (full_row) {
            for (int i = 0; i < 6; i++) rowstr += to_string(grid[row][i]);
            if (vis_row.count(rowstr)) flag = 0; // 如果该行已出现过,则剪枝
            else vis_row.insert(rowstr); // 否则,将其加入已出现行的集合
        }
        if (full_col) {
            for (int i = 0; i < 6; i++) colstr += to_string(grid[i][col]);
            if (vis_col.count(colstr)) flag = 0; // 如果该列已出现过,则剪枝
            else vis_col.insert(colstr); // 否则,将其加入已出现列的集合
        }

        // 如果通过了所有剪枝,则递归地搜索下一个格子
        if (flag && solve(pos + 1)) return 1;

        // --- 回溯:撤销当前尝试的操作,恢复现场 ---
        if (full_row) vis_row.erase(rowstr);
        if (full_col) vis_col.erase(colstr);
        grid[row][col] = -1;
        if (val) {
            black_row[row]--;
            black_col[col]--;
        } else {
            white_row[row]--;
            white_col[col]--;
        }
    }
    return 0; // 如果当前格子尝试了两种颜色都无法得到解,则返回 0
}

int main() {
    // 程序开始前,先根据初始棋盘,初始化每行每列的黑白棋数量
    for (int i = 0; i < 6; i++) {
        for (int j = 0; j < 6; j++) {
            if (grid[i][j] == 1) {
                black_row[i]++;
                black_col[j]++;
            } else if (grid[i][j] == 0) {
                white_row[i]++;
                white_col[j]++;
            }
        }
    }
    // 从第一个格子(编号 0)开始深度优先搜索
    if (solve(0)) {
        cout << ans << endl; // 输出最终找到的答案字符串
    }
    return 0;
}

目录

  1. 题目一:寻找质数
  2. 题目描述
  3. 解题步骤
  4. C++ 参考代码
  5. 运行结果
  6. 题目二:黑白棋
  7. 题目回顾与核心规则
  8. 核心解题思路:深度优先搜索(DFS)+ 剪枝
  9. C++ 完整源码
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Flutter 三方库 eth_sig_util 鸿蒙适配指南:以太坊加密签名核心实现
  • Flutter eip55 库在 OpenHarmony 上的适配与以太坊地址校验
  • OpenClaw AI 助手跨设备迁移指南
  • Flutter eip55 库在鸿蒙系统的适配与以太坊地址校验实战
  • Python 实现 GraphQL:从原理到企业级实战
  • Transformer 位置编码原理与实现
  • Flutter 三方库 cached_query 为鸿蒙应用打造高性能声明式数据缓存系统
  • 机器学习十大核心算法原理与 Python 实现
  • Qwen2 大模型源码解析
  • Flutter 使用 eip55 库实现鸿蒙系统以太坊地址校验适配
  • Spring Boot @Async 与 @Transactional 结合使用原理与避坑指南
  • Flutter 三方库 dart_webrtc 的鸿蒙化适配指南
  • 鸿蒙高性能编程:使用 Napi 让 ArkTS 调用 C++ 算法库
  • CVPR 2025 论文总结:黑暗中的重构与去噪新视角与通用架构
  • OSCP 实战:传递 Net-NTLMv2 哈希攻击技术详解
  • Flutter 三方库 Bavard 鸿蒙化适配:语义化聊天协议与机器人逻辑
  • IntelliJ IDEA 中修改 Git 用户名、邮箱及切换账号
  • Flutter 三方库 bavard 鸿蒙适配:语义化聊天协议与分布式通讯
  • Python 开发效率提升:20 个常用 PyCharm 插件推荐
  • Flutter 三方库 tiktoken 在鸿蒙端侧的 AI 适配与 Token 计算指南

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online