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

CCF-GESP 三级 C++ 真题:最小花费购物

题目要求对每种文具只保留最低价格并求和。直接做法是用数组维护每个种类的最小值,读入每件文具时即时更新,最后遍历 1 到 M 累加即可,时间复杂度 O(N+M)。如果习惯先整理数据,也可以把文具按种类和价格排序,再取每类排在最前面的价格,复杂度 O(N log N)。

小熊软糖发布于 2026/6/300 浏览

题目描述

小杨的班级要举办一个环保手工作品展览,老师请小杨去文具店购买 M 种不同的文具(例如:铅笔、橡皮、尺子等)。

商店里共有 N 件文具,每件文具都有一个种类编号(从 1 到 M)和价格。

小杨的预算有限,他的做法很直接:每种文具只买最便宜的那一件;如果同一种文具有多件价格相同且都最便宜,他也只拿其中一件。请你算出,买齐这 M 种文具一共要花多少钱。

输入格式

第一行两个正整数 M,N,代表文具的种类数和总数。

之后 N 行,每行两个正整数 Ki 和 Pi,分别代表第 i 件文具的种类编号和它的价格。数据保证每个种类至少有一件文具可供购买。

输出格式

输出一行,代表购买文具的总价。

输入输出样例 #1

输入 #1
2 5
1 1
1 2
1 1
2 3
2 10
输出 #1
4

说明/提示

样例解释

文具清单如下:

  • 文具 1:种类 1,价格 1
  • 文具 2:种类 1,价格 2
  • 文具 3:种类 1,价格 1
  • 文具 4:种类 2,价格 3
  • 文具 5:种类 2,价格 10

小杨的选择很简单:种类 1 里最便宜的是 1,种类 2 里最便宜的是 3。总价就是 1+3=4。

数据范围

对于所有测试点,保证 1≤M≤N≤10^5,1≤Ki≤M,1≤Pi≤10^3。

题解:按种类取最小值

这题其实就是统计每个种类的最低价格,然后把这些最低价加起来。题目保证每个种类都至少出现一次,所以不用处理'某类没货'的情况。数据规模到 10^5,做法得老实一点,不能靠暴力扫多轮。

思路一:直接维护每类最小值

我更倾向于这种写法,简单,也不容易出错。

读入每一件文具时,直接更新它所属种类的最低价。因为价格都是正整数,可以用一个数组 mn 记录每类当前最小值。mn[k] 还没被赋值时为 0,第一次见到这个种类就直接写入,后面再拿 min 比一下即可。

最后再把 1..M 这些种类的最小价加起来,答案就出来了。

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

int n, m; // n:文具总数,m:文具种类数
int k, p; // k:种类编号,p:价格
int mn[100005]; // mn[i] 记录第 i 种文具的最低价格
int ans = 0; // 总价

int main() {
    cin >> m >> n;

    for (int i = 1; i <= n; i++) {
        cin >> k >> p;
        if (mn[k] == 0) {
            mn[k] = p;
        } else {
            mn[k] = min(mn[k], p);
        }
    }

    for (int i = 1; i <= m; i++) {
        ans += mn[i];
    }

    cout << ans;
    return 0;
}

思路二:排序后取每类第一个

如果你更习惯先把数据整理好,再做统计,也可以用排序。

把所有文具按'种类升序、价格升序'排序。这样同一种类会挨在一起,而且排在最前面的就是这个种类的最低价。遍历排序后的数组,只要当前元素的种类和前一个不同,就说明碰到了一个新种类,把它的价格加进答案里就行。

这套写法也能过,不过我会更偏向上面的数组做法,因为它不需要排序,读一遍就结束,思路更短。

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

int n, m;

struct node {
    int k;
    int p;
};

node a[100005];
int ans = 0;

bool cmp(node x, node y) {
    if (x.k == y.k) {
        return x.p < y.p;
    }
    return x.k < y.k;
}

int main() {
    cin >> m >> n;

    for (int i = 1; i <= n; i++) {
        cin >> a[i].k >> a[i].p;
    }

    sort(a + 1, a + n + 1, cmp);

    for (int i = 1; i <= n; i++) {
        if (a[i].k != a[i - 1].k) {
            ans += a[i].p;
        }
    }

    cout << ans;
    return 0;
}

复杂度分析

  • 方法一:时间复杂度 O(N+M),空间复杂度 O(M)
  • 方法二:时间复杂度 O(N log N),空间复杂度 O(N)

题目数据不大,两种都能稳稳通过。实际做题时,直接维护最小值通常更省事,也更不容易写错。

目录

  1. 题目描述
  2. 输入格式
  3. 输出格式
  4. 输入输出样例 #1
  5. 输入 #1
  6. 输出 #1
  7. 说明/提示
  8. 样例解释
  9. 数据范围
  10. 题解:按种类取最小值
  11. 思路一:直接维护每类最小值
  12. 思路二:排序后取每类第一个
  13. 复杂度分析
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • 无人机检测数据集整理:11998 张图像与多格式标注
  • PowerShell 中激活 Python 虚拟环境的几种办法
  • OpenClaw 飞书多 Agent 对接与隔离配置
  • Web 端 3D 开发的实用技术栈梳理
  • GitHub Copilot 学生认证排查笔记
  • LLM 训练怎么走:预训练、微调和 RLHF
  • 用 DevUI 和 MateChat 做企业级 AI 助手
  • 腾讯三款 AI Agent 怎么选:WorkBuddy、QClaw、CodeBuddy 实测
  • 提升 PyTorch 训练效率的 9 个实用做法
  • 通义万相 2.1 的架构、能力与落地观察
  • 大语言模型原理、应用与演进路线
  • Seedance 2.0 实测:AI 视频从“能看”走向“能用”
  • C++ 虚函数表与多态实现原理
  • 华为机试:素数伴侣的二分图匹配解法
  • Python 学习路线:先打基础,再做项目
  • 大模型面试题整理:RAG、SFT、RLHF 与核心架构
  • USB-Blaster 驱动安装与 FPGA 下载排障
  • Open3D.Art 生成模型到拓竹打印的实用流程
  • Python 3.11 新特性:性能、异常与类型系统的变化
  • RISC-V 处理器从 RTL 到 FPGA 验证实录

相关免费在线工具

  • 加密/解密文本

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