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

C++ 算法刷题:平方数、分组与拓扑排序

包含三道 C++ 算法题。第一题求最近平方数,利用 sqrt 函数计算;第二题分组问题,通过统计声部人数并使用二分查找确定最小化最大组人数;第三题为拓扑排序模板,使用入度表和队列实现。代码已优化格式并修正逻辑错误。

黑客帝国发布于 2026/3/28更新于 2026/9/973 浏览
C++ 算法刷题:平方数、分组与拓扑排序

一、平方数

题目解析

图片描述

题目给出一个数,找到离它最近的一个平方数并输出。

算法思路

一种思路是从 1 开始找,找到小于 x 的最大平方数 l 和大于 x 的最小平方数 r,比较差值。更简便的方法是利用 sqrt 函数:

我们知道 sqrt 函数可以对一个数进行开根号运算,返回 double 类型数据;

将该返回值强转为整型即拿到 l,再对其加一即拿到 r。

这样该数在区间 [ll, rr] 内,判断 rr - x 和 x - ll 哪个最小即可。

图片描述

代码实现

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

int main() {
    long long x;
    cin >> x;
    long long a = sqrt(x);
    long long l = a * a, r = (a + 1) * (a + 1);
    if (x - l > r - x) cout << r << endl;
    else cout << l << endl;
    return 0;
}

二、分组

题目解析

图片描述

题目描述:将 n 个同学分成 m 个组,每个同学擅长一个声部,同组同学可擅长不同声部,但同一声部的同学必须分在不同组(或理解为同声部人数限制)。目标是使每组人数尽可能少,若无法安排输出 -1,否则输出组中最多的人数。

题意转换:输入 n, m,表示 n 个人分 m 个组,随后 n 个数表示每个同学擅长的声调。

算法思路

初始思路尝试使用堆,但效率较低。正确的解决思路是二分答案:

假设每个组中最多有 x 人,若某声调有 y 人,则需分成 y/x 个组(向上取整)。

统计所有声调需要的总组数 sum。若 sum > m,说明 x 取小了,增大 x;若 sum <= m,说明可行,尝试减小 x。

在区间 [1, hmax] 中二分查找满足条件的最小 x。

图片描述

代码实现

首先统计每种声调的人数及最大值 hmax。若声调种类数大于 m,直接输出 -1。否则使用二分查找。

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

int n, m;
unordered_map<int, int> cnt;

bool check(int x) {
    int sum = 0;
    for (auto& e : cnt) {
        sum += (e.second / x + (e.second % x == 0 ? 0 : 1));
    }
    return sum <= m;
}

int main() {
    cin >> n >> m;
    int hmax = 0;
    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
        cnt[x]++;
        if (cnt[x] > hmax) hmax = cnt[x];
    }
    
    if (cnt.size() > m) {
        cout << -1 << endl;
    } else {
        int left = 1, right = hmax;
        while (left < right) {
            int mid = (left + right) / 2;
            if (check(mid)) right = mid;
            else left = mid + 1;
        }
        cout << left << endl;
    }
    return 0;
}

三、【模板】拓扑排序

题目解析

图片描述

考查拓扑排序,给定包含 n 个点、m 条边的有向无环图,输出拓扑序列。

输入:n, m,随后 m 行每行两个整数 v1, v2 表示 v1 到 v2 的有向边。

算法思路

拓扑排序步骤:

  1. 选择入度为 0 的节点输出。
  2. 删除该节点及其发出的所有边。
  3. 重复直至所有节点输出。

实现细节:

  • 记录有向边:vector<vector<int>>,下标为起点,值为终点列表。
  • 记录入度:vector<int>。
  • 队列 queue 存放当前入度为 0 的节点。
  • 结果存储:vector<int>,若最终大小等于 n 则存在拓扑序,否则输出 -1。

注意:输出结果时最后一个字符后不能有空格。

代码实现

#include <iostream>
#include <queue>
#include <vector>
using namespace std;

int main() {
    int n, m;
    cin >> n >> m;
    vector<vector<int>> arr(n + 1);
    vector<int> hash(n + 1);
    
    for (int i = 0; i < m; i++) {
        int x, y;
        cin >> x >> y;
        hash[y]++;
        arr[x].push_back(y);
    }
    
    queue<int> q;
    for (int i = 1; i <= n; i++) {
        if (hash[i] == 0) q.push(i);
    }
    
    vector<int> ret;
    while (!q.empty()) {
        int x = q.front();
        q.pop();
        ret.push_back(x);
        
        for (auto& e : arr[x]) {
            hash[e]--;
            if (hash[e] == 0) {
                q.push(e);
            }
        }
    }
    
    if (ret.size() == n) {
        for (int i = 0; i < ret.size(); i++) {
            cout << ret[i];
            if (i < ret.size() - 1) cout << ' ';
        }
        cout << endl;
    } else {
        cout << -1 << endl;
    }
    return 0;
}

目录

  1. 一、平方数
  2. 题目解析
  3. 算法思路
  4. 代码实现
  5. 二、分组
  6. 题目解析
  7. 算法思路
  8. 代码实现
  9. 三、【模板】拓扑排序
  10. 题目解析
  11. 算法思路
  12. 代码实现

更多推荐文章

查看全部
  • 宇树 G1 机器人开发:有线与无线连接配置实战
  • AI 大模型通信机制:流式传输与数据封装逻辑解析
  • OpenHarmony 下 Flutter 跨域难题:flutter_cors 实战与适配方案
  • DeepSeek、Kimi 等 5 款 AI 写作工具实测与推荐
  • OpenClaw 30+ 真实使用案例开源,参考 AI 助理落地方案
  • Whisper 本地部署完整指南:语音转文字
  • ibbot(智体机灵):国产开源AI智能体平台解析
  • ESLint 核心原理与工程化实践指南
  • IntelliJ IDEA 中 Git 更新项目:合并与变基操作指南
  • Retrieval-based-Voice-Conversion-WebUI 跨平台语音转换指南
  • AI 创作入门:普通人如何通过互动实现成长
  • 宇树 G1 机器人开发:有线与无线连接配置指南
  • Web of Science 英文数据库检索指南与练习
  • 使用 Continue 插件本地部署 AI 代码助手替代 Cursor 或 Copilot
  • XSS 攻击原理、类型与实战防御指南
  • Microsoft Visual C++ Redistributable 运行库安装与修复指南
  • Stable Diffusion 绘画实战:云端部署与提示词技巧
  • Git 连接 GitHub 端口 443 失败解决方案
  • Python 家庭用电数据分析与 Prophet 时间序列预测
  • MCP 协议详解:与 Function Call 的区别及实战

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如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