C++竞赛级输入输出优化实战
一、输入方式
1. cin
基础用法
-
跳过空白符读取:
int a; double b; string s; cin >> a >> b >> s; // 自动跳过空格/换行符
- 按变量类型读取,遇到空白符停止。
-
缺点:不处理类型不匹配的情况(如输入字符给整型变量)。
-
读取单个字符:
char c; cin >> c; // 跳过空白符,读取第一个非空白字符 cin.get(c); // 读取任意字符(包括空格/换行)
-
整行读取:
string line; getline(cin, line); // 读取到换行符(换行符被丢弃)
- 注意:前序输入可能残留换行符,需先执行
cin.ignore()
。
- 注意:前序输入可能残留换行符,需先执行
2. scanf
格式化输入
-
基本格式符:
int a; double b; char str[100]; scanf("%d %lf %s", &a, &b, str); // 注意:%lf对应double,%s以空格/换行结束
- 常用格式符:
%d
(int)、%lld
(long long)、%c
(字符)、%f
(float)、%lf
(double)。 - 安全字符串读取:
scanf("%9s", str);
(限制最大长度为9,防止溢出)。
- 常用格式符:
-
特殊用法:
- 忽略特定字符:
scanf("%d,%d", &a, &b); // 输入格式如 "123,456"
- 扫描集(读取特定字符集合):
scanf("%[a-zA-Z]", str); // 只读取字母
- 忽略特定字符:
3. 高效读取(算法竞赛优化)
-
禁用同步 & 解绑:
ios::sync_with_stdio(false); // 关闭与stdio的同步 cin.tie(nullptr); // 解除cin与cout的绑定(减少刷新)
此后仅使用
cin/cout
,不可混用scanf/printf
。 -
读取优化示例:
#include <iostream> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; // 后续使用cin快速读取... }
二、输出方式
1. cout
基础用法
-
直接输出:
int a = 10; double b = 3.1415926; cout << a << " " << b << endl;
-
控制小数精度:
#include <iomanip> cout << fixed << setprecision(2) << b; // 输出 3.14(四舍五入)
2. printf
格式化输出
- 常用格式符:
printf("%d\n", a); // 整数 printf("%10d\n", a); // 宽度10,右对齐 printf("%-10d\n", a); // 左对齐 printf("%.2f\n", b); // 两位小数 printf("%08d\n", a); // 宽度8,前导零填充
- 技巧:
%lld
(long long)、%x
(十六进制)。
- 技巧:
3. 输出优化
- 避免频繁刷新:使用
'\n'
代替endl
。cout << a << '\n'; // 比endl更快
三、特殊场景处理
1. 混合输入类型
- 示例:先读整数,再读一行。
int n; string s; cin >> n; cin.ignore(); // 清除之前残留的换行符 getline(cin, s);
2. 字符串流分割
#include <sstream>
string line = "1 2 3";
istringstream iss(line);
int a, b, c;
iss >> a >> b >> c; // 分割字符串内容
四、算法竞赛建议
- 输入优先选
scanf
(更快),或优化后的cin
。 - 输出优先选
printf
(格式控制灵活)。 - 对时间要求极高时,关闭同步+解绑(保证不混用C/C++ IO)。
- 处理大规模数据前,预分配容器内存(如
vector.reserve()
)。
通过上述方式系统梳理,结合高频使用场景和效率优化技巧,在算法竞赛中可显著提升代码效率并减少调试时间。