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

C/C++ 输入输出实战:OJ 场景处理与性能优化

C/C++ 输入输出是算法竞赛的基础,涉及单组与多组测试数据读取、特殊字符处理及流对象性能差异。 scanf/printf 与 cin/cout 的格式控制区别,分析同步机制导致的性能瓶颈,并提供 ios::sync_with_stdio(false) 等优化方案,帮助开发者在大规模数据输入时避免超时,写出高效健壮的代码。

雪落无声发布于 2026/3/23更新于 2026/6/3033 浏览
C/C++ 输入输出实战:OJ 场景处理与性能优化

在算法竞赛中,输入输出(I/O)是程序与外部交互的基础。C 和 C++ 提供了强大的 I/O 机制,从 C 风格的 scanf/printf 到 C++ 的流式操作 cin/cout,看似简单,实则暗藏玄机。许多开发者在使用过程中可能会遇到缓冲区问题、格式控制陷阱或性能瓶颈。本文将结合实际 OJ 题目,梳理常见输入场景,并深入探讨性能差异与优化方案。

OJ 题目输入情况汇总

在竞赛环境中,输入场景通常可以归纳为以下几类,理解这些模式有助于快速构建解题框架。

单组测试用例

这类题目通常只包含一组数据,读取后计算并输出即可。

示例:计算 (a+b)/c 的值

#include<iostream>
using namespace std;

int main(){
    int a, b, c;
    cin >> a >> b >> c;
    cout << (a + b) / c << endl;
    return 0;
}

示例:与 7 无关的数

思路是先找出与 7 相关的正整数(被 7 整除、个位是 7、十位是 7),然后取反得到无关的数。由于 n < 100,只需遍历判断。

#include<iostream>
using namespace std;

int main(){
    int n;
    cin >> n;
    int i = 1;
    int sum = 0;
    while(i <= n){
        if(i % 7 != 0 && i % 10 != 7 && i / 10 != 7){
            sum += (i * i);
        }
        i++;
    }
    cout << sum << endl;
    return 0;
}

多组测试用例

测试数据组数已知

当题目明确告知有 N 组数据时,先读入 N,再循环处理。

示例:多组输入 a+b II

#include<iostream>
using namespace std;

int main(){
    int n; // 表示数据组数
    cin >> n;
    int a, b; // 每行输入的 a,b 值
    while(n--){
        cin >> a >> b;
        cout << a + b << endl;
    }
    return 0;
}

示例:斐波那契数列

对于范围受限的情况(如 1~30),预处理数组直接查表效率更高;若范围较大,则需动态计算。

#include<iostream>
using namespace std;

int main(){
    int n, a, i;
    int ret[35] = {0, 1, 1};
    for(i = 3; i < 30; i++){
        ret[i] = ret[i - 1] + ret[i - 2];
    }
    cin >> n;
    while(n--){
        cin >> a;
        cout << ret[a] << endl;
    }
    return 0;
}
测试数据组未知

当不知道有多少组数据时,通常利用输入流的返回值作为循环条件。

示例:多组输入 a+b

cin >> a >> b 会返回流对象引用,成功读取时为 true,遇到文件结束符或错误时为 false。

#include<iostream>
using namespace std;

int main(){
    int a, b;
    while(cin >> a >> b){
        cout << a + b << endl;
    }
    return 0;
}
特殊值结束测试数据

有时题目会以特定数值(如 0 0)作为结束标志。

示例:多组数据 a+b III

利用逗号表达式,当且仅当 a 和 b 都不为 0 时继续循环。

#include<iostream>
using namespace std;

int main(){
    int a = 0, b = 0;
    while(cin >> a >> b, a && b){
        cout << a + b << endl;
    }
    return 0;
}

输入时的特殊技巧

含空格字符串的处理

读取带空格的字符串时,cin 默认以空格为分隔符。如果需要完整读取一行,可使用 getline;如果只需处理单词,直接循环 cin 即可。

示例:统计数字字符个数

方法一:一次性读取整行。

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

int main(){
    string s;
    getline(cin, s);
    int ret = 0;
    for(auto ch : s){
        if(ch >= '0' && ch <= '9'){
            ret++;
        }
    }
    cout << ret << endl;
    return 0;
}

方法二:逐个单词读取。

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

int main(){
    string s;
    int cnt = 0;
    while(cin >> s){
        for(auto c : s){
            if(c >= '0' && c <= '9') cnt++;
        }
    }
    cout << cnt << endl;
    return 0;
}

数字的特殊处理

输入的数字既可以是整数类型,也可以是字符串。根据需求选择处理方式。

示例:小乐乐改数字

法一:当做整数读取,通过 % 10 和 / 10 逐位处理。

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

int main(){
    int n;
    int i = 0, ret = 0;
    cin >> n;
    while(n){
        if(n % 10 % 2 == 1){
            ret += pow(10, i);
        }
        n /= 10;
        i++;
    }
    cout << ret << endl;
    return 0;
}

法二:当做字符串处理,利用 ASCII 码特性判断奇偶。

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

int main(){
    string s;
    cin >> s;
    for(int i = 0; i < s.size(); i++){
        if(s[i] % 2){
            s[i] = '1';
        } else {
            s[i] = '0';
        }
    }
    cout << stoi(s) << endl;
    return 0;
}

scanf/printf 和 cin/cout 的对比

scanf/printf 是 C 语言标准库函数,cin/cout 是 C++ 流对象。两者各有优劣。

格式控制差异

  • scanf/printf 需要手动指定格式字符串,容易出现类型不匹配导致的未定义行为,但格式化输出更精确直观。
  • cin/cout 会根据变量类型自动处理,避免格式错误,易用性更强。
#include<cstdio>
#include<iostream>
using namespace std;

int main(){
    float a = 3.50;
    double d = 16.50;
    cout << "cout: " << a << " " << d << endl;
    printf("printf: %f %lf\n", a, d);
    return 0;
}

区别在于 cout 默认忽略多余小数位,而 printf 默认打印 6 位小数。

性能差异

在数据量较大时,scanf/printf 通常比 cin/cout 快。这是因为 C++ 流对象为了兼容 C 语言,默认开启了同步机制,导致每次操作都涉及缓冲区刷新。

案例演示:

在处理大量数据时,直接使用 cin 可能导致超时(TLE)。例如在排序或位运算题目中,输入规模达到百万级时,性能差异尤为明显。

优化方案:

可以通过以下代码取消同步并解绑流,使 cin/cout 的性能接近 scanf/printf。

ios::sync_with_stdio(false); // 取消 C 语言输入输出缓冲区的同步
cin.tie(0);                  // 取消 cin 和 cout 的绑定

总结建议:

  • 数据量较小(10^6 以内):使用习惯即可,推荐 cin/cout 以保持代码简洁。
  • 数据量较大(10^9 左右或严格时限):推荐使用 scanf/printf 或优化后的 cin/cout。
  • 极端情况下:可考虑手写快速读写模板。

掌握输入输出的底层机制和陷阱,才能写出健壮高效的代码。从缓冲策略到格式控制,每个细节都可能成为调试时的关键。

目录

  1. OJ 题目输入情况汇总
  2. 单组测试用例
  3. 多组测试用例
  4. 测试数据组数已知
  5. 测试数据组未知
  6. 特殊值结束测试数据
  7. 输入时的特殊技巧
  8. 含空格字符串的处理
  9. 数字的特殊处理
  10. scanf/printf 和 cin/cout 的对比
  11. 格式控制差异
  12. 性能差异
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • 全 Web 化智慧 PACS/RIS 系统架构解析
  • AIGC时代Kubernetes企业级云原生运维实战:智能重构与深度实践指南
  • Linux 初始网络(下):局域网通信与跨网段传输原理
  • 无线蜂窝网络原理与演进:从 1G 到 6G
  • Flink History Server 查看已完成作业 Web UI 与 REST 数据
  • Figma + Claude + Weavy AI 设计工作流实战
  • 基于 Figma、Claude 与 Weavy AI 的 UI 设计工作流实战
  • FFmpeg 8.0 集成 Whisper 实现语音识别功能
  • 本地 AI 智能体 OpenClaw 功能特性与常用指令详解
  • nanobot 轻量级 AI Agent 框架搭建 QQ 机器人实践与开源贡献
  • 几款主流免费 AI 视频生成工具推荐
  • 基于 Python + Django 的电商小项目实战
  • IntelliJ IDEA 免费 AI 代码提示插件推荐
  • 12 个 AI 免费一键生成 PPT 网站推荐
  • Spring Cloud Gateway 核心机制与高性能原理实战
  • 深入解析 Redisson 分布式锁核心原理与源码实现
  • 分布式配置中心深度解析:Spring Cloud Config 与 Apollo 架构对比
  • OpenClaw 本地优先智能体框架架构与工程实践
  • Git 分布式版本控制:安装、配置与实战指南
  • 分布式版本控制系统 Git 的安装与实战指南

相关免费在线工具

  • 加密/解密文本

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