行业资讯
📅 2026/9/1 8:23:31
NOI题库1.1输入输出全攻略:C++入门必刷的20道题与避坑指南
简介面向NOI入门学习者与OpenJudge刷题用户的C题解合集覆盖1.1编程基础之输入输出全部10道题目适合刚接触信息学竞赛、需要对照标准思路巩固基础语法的人群。压缩包仅含10个cpp源文件整体大小4KB每个文件对应一道题代码结构简洁可直接在本地编译或提交至OJ验证。已有5107人学习下载足见其作为入门资料的实用价值。文件命名与题目序号一一对应从最基础的Hello World到字符菱形、超级玛丽游戏完整展示了printf格式化输出、setprecision精度控制、空格与换行处理等高频考点的实现方式。读者可针对自己的薄弱环节如浮点数保留位数、字符图形拼接快速找到对应源码参考AC思路并理解边界细节减少OJ调试时间。 很多人第一次打开 NOI 题库都会被 1.1 这一章整得有点懵题目明明看着都是“输出几个字符”“打印个三角形”这种级别可一提交就满屏的红色 WA甚至编译错误。作为一个带过不少学生从零刷 NOI 题库的老选手我可以直接告诉你1.1 这组“编程基础之输入输出”题目恰恰是筛掉一批人的第一道坎。它不考算法考的是你对 C 基本功的掌握程度——头文件、格式化输出、转义字符、ASCII 码、输入陷阱全在这 20 来道题里藏着。这篇东西就是来送福利的。我会把 NOI 题库 1.1 的题型分布、每类题的核心解法、完整可提交的参考代码还有我自己踩过的坑、帮学生排查过的问题全部整理出来。不管你是在备赛 NOI/NOIP还是刚学 C 想找点靠谱的练习这组题都值得你认真过一遍。尤其是那些“明明本地跑得好好的一交上去就错”的玄学问题这篇文章里我会专门讲清楚原因。1. NOI题库1.1到底在考什么——先看懂这组题的设计逻辑1.1 这组题在NOI知识体系中的位置NOI 题库也就是大家常说的 OpenJudge 上的 NOI 题库1.1 章节官方名称是“编程基础之输入输出”。从章节标题就能看出来这组题面向的是刚接触编程的选手目标是让你在正式接触算法之前先把“程序怎么读数据、怎么把结果输出成题目要求的样子”这双基本功练扎实。但千万别小看这组题在整条备赛路线上的地位。我自己见过太多选手学到动态规划、图论的时候回头补基础才发现连个浮点数保留小数位都能输出错。信息学竞赛的评测系统是机器比对输出结果的差一个空格、多一个换行哪怕你的算法完全正确结果也是 0 分。1.1 这章的存在意义就是让你在付出“算法代价”之前先把“格式代价”这个最容易丢分的坑填平。从题目难度梯度来看1.1 做得也很有讲究。题号从 01 到 20 左右前几道是纯粹的“直接输出固定内容”中间几道是“读入数据再按格式输出”最后几道开始混入简单的数学计算和 ASCII 码处理。这个梯度设计非常符合认知规律先让你学会“说话”输出再教你“听别人说话”输入最后让你“边听边算”输入运算输出。1.2 完整题目清单与考点分布我把 1.1 章节里出现频率最高、最容易在考试/练习中被引用的题目整理成了表格方便你对照检查自己哪些还没刷过题号题目名称核心考点难度01Hello, World!cout/cout 基础输出、大小写与标点入门02输出第二个整数cin 连续读入、输出指定变量入门03对齐输出printf 格式控制、%8d 右对齐入门04输出保留3位小数的浮点数printf 小数位控制 %.3f入门05空格分隔输出scanf 读入多种类型、输出顺序入门06输出浮点数%f / %e 等多种格式输出入门07字符三角形字符变量输出、空格的规律简单08字符菱形字符图形输出的规律总结简单09字符菱形变体循环或直接输出的选择简单10超级玛丽游戏转义字符、长文本逐行输出中等11地球人口承载力估计数学建模、浮点数输出中等需要注意的是不同版本的题库在题号顺序上可能略有差异但核心题目基本就是上面这些。你不需要纠结具体题号关键是搞清楚题目到底在考察什么能力。2. 核心题型逐个拆解——每道题背后的输出思维2.1 Hello World与世界上的第一个程序先看最经典的 01 题。题目要求输出Hello, World!一个空格、一个逗号、一个感叹号都不能少。这题对老手来说当然毫无压力但它揭示了一个非常重要的原则评测系统只认字符不认“意思”。你输出Hello World!和Hello, World!人眼看起来差不多但机器判定就是两个完全不同的字符串。我见过不少初学者在这道题上翻车原因五花八门把逗号打成中文逗号、把World写成Word、在行尾多打了一个空格。这里分享一个排查习惯每次提交前先盯着题目原文的“输出样例”逐字符核对一遍一个字符一个字符地比。具体代码很简单#include iostream using namespace std; int main() { cout Hello, World! endl; return 0; }如果你是老实用printf的选手写成这样也一样#include cstdio int main() { printf(Hello, World!\n); return 0; }习惯上NOI 系列比赛更推荐你用printf/scanf而不是cin/cout理由后面在 3.2 我会详细说。2.2 格式化输出对齐、补位、保留小数1.1 中间那几道题核心就是 C 风格格式化输出%d、%f、%lf、%e加上宽度控制%8d和精度控制%.3f。这里直接给你一个“可以抄作业”的速查表格式含义示例%d输出整数printf(%d, 42);%5d整数占5位宽右对齐printf(%5d, 42); 输出为 42%-5d整数占5位宽左对齐printf(%-5d, 42);%.3f浮点数保留3位小数printf(%.3f, 3.14159);%8.3f浮点数占8位宽保留3位小数printf(%8.3f, 3.14159);%e科学计数法输出printf(%e, 123.456);以 03 题“对齐输出”为例题目要求读入三个整数按每个整数占 8 个字符宽度右对齐输出。标准写法是#include cstdio int main() { int a, b, c; scanf(%d%d%d, a, b, c); printf(%8d %8d %8d\n, a, b, c); return 0; }注意一眼就能看到的两个陷阱第一%8d是让数字占 8 个字符宽度如果数字本身超过 8 位则按实际宽度输出不会截断第二相邻两个整数之间还有个空格这个空格是在格式串里手动写进去的别漏了。这两点就是这组题想让你练的“输出细节敏感度”。2.3 字符图形输出三角形、菱形与ASCII表的活用字符图形类的题是最容易让初学者“脑子转不过弯”的。比如字符三角形输入一个字符*输出* *** *****注意第二行前面有 1 个空格第一行前面有 2 个空格。如果你观察力够敏锐会发现规律一共有 3 行第 i 行有3-i个空格i 从 1 开始有2*i-1个字符。但对于 1.1 这种入门章节直接用三句printf写完完全没有问题#include cstdio int main() { char c; scanf(%c, c); printf( %c\n, c); printf( %c%c%c\n, c, c, c); printf(%c%c%c%c%c\n, c, c, c, c, c); return 0; }很多老师会强调“要学循环”但我的观点是入门阶段先用最直接的方式解决能帮你快速建立信心。等你刷到后面 1.5 循环章节自然会回来用for重写一遍那时候你对循环的理解会比直接硬学深刻得多。字符菱形也是一样的套路输入一个字符输出一个 5 行的菱形* *** ***** *** *可以直接上下对称拼两个三角形也可以自己找每行空格和字符的数学规律。我个人建议你试着用循环写一版因为这算是“从输出到算法”的第一个思维跳跃点值得多花 10 分钟琢磨。3. 从0到1完整实操——手把手带你写完这组题3.1 环境准备与提交规范工欲善其事必先利其器。刷 NOI 题库我建议你本地装一个 Dev-C 5.11 或者 Visual Studio Code MinGW 组合只要能编译运行 C 代码就行。关于语言标准NOI 系列比赛现在主要用 C14你写这组入门题目时用的语法在 C98 下都能跑所以不用担心标准问题。提交的时候有一个细节容易被忽略确认题目要求的是 C 还是 C 语言。NOI 题库的 1.1 章节两种语言都能交但你本地写的代码必须和提交语言一致。见过有人本地用 C 语法写着#include stdio.h提交时忘了选语言默认 C 也能编译过但有些版本会报错所以每次提交前检查一下语言选项。另外一个必须养成的习惯是提交前先看题目输入输出样例自己本地跑一遍样例。不是跑通就算过而是要把样例输入、样例输出逐字符比对。我一般会在本地把输出结果重定向到文件然后用文件对比工具比如diff命令或者 VS Code 里的比较功能对比确保完全一致。3.2 printf/scanf 还是 cin/cout这是个比赛习惯问题1.1 这组题用cin/cout和printf/scanf都能过因为数据量太小了。但从备赛的第一天起我强烈建议你直接上手printf/scanf。原因很简单到了后面的题目数据量动辄十万、百万级别cin/cout默认的同步和缓冲机制会导致明显的性能损耗虽然可以加ios::sync_with_stdio(false)来优化但在考场上每个人都会紧张多一个变量就多一分出错的可能。不如从一开始就用printf/scanf一劳永逸。用scanf的时候有个头文件的问题C 里printf和scanf在cstdio头文件中声明有些编译器也能用stdio.h但比赛环境通常两者兼容。为了稳妥我统一用cstdio你如果用的是#include bits/stdc.h这种万能头文件本地没问题但部分比赛环境可能不支持建议从一开始就规范头文件写法。3.3 这三道高频题的完整实现与逐行解读第一道必须吃透的是 02 题“输出第二个整数”。题目输入三个整数要求输出第二个。解法#include cstdio int main() { int a, b, c; scanf(%d%d%d, a, b, c); printf(%d\n, b); return 0; }这段代码里scanf的%d%d%d写法允许输入用空格或换行分隔三个整数scanf会自动跳过空白字符。这是 C 风格输入最重要的特性之一它不关心你输入的是空格、Tab 还是换行。第二道是 04 题“输出保留3位小数的浮点数”。输入一个单精度浮点数输出它保留 3 位小数后的结果#include cstdio int main() { float f; scanf(%f, f); printf(%.3f\n, f); return 0; }注意scanf读float用%f读double要用%lf但printf里%f和%lf是通用的参数传递时 float 会转成 double。这个区别极其容易搞混C 语言的这个设计坑了无数人你只需要记住“输入严格区分输出可以通用”这个口诀。第三道是有一定数学含量的 11 题“地球人口承载力估计”。题目大意是假设地球上的新生资源按恒定速度增长现有资源加上新生资源可供 x 亿人生活 y 年或者供 z 亿人生活 w 年求地球最多能养活多少亿人。这题需要先推出公式。设现有资源为 A每年新生资源为 B每个人每年消耗 1 份资源则A B * y x * y A B * w z * w两式相减可得B (x * y - z * w) / (y - w)这里的 B 就是每年新生资源量也就是地球能持续养活的最大人口数超过这个数就会逐年消耗存量资源。输出保留两位小数用%.2f#include cstdio int main() { double x, y, z, w; scanf(%lf%lf%lf%lf, x, y, z, w); double ans (x * y - z * w) / (y - w); printf(%.2f\n, ans); return 0; }这道题是 1.1 章节里唯一一道需要你“动点脑子”的题它传递的信号是编程入门不只是学语法还要学会把数学表达式翻译成代码。很多人在这道题上卡住不是因为不会写代码而是因为没推出公式。所以当你遇到一道题完全没思路时先拿纸笔算一算再考虑敲代码。3.4 把训练计划plan变成可执行的节奏你可能会问这组题一共就 20 来道我应该花几天刷完我见过两种极端一种是一下午全写完然后转头就忘另一种是一周才写了 5 道越拖越没动力。我的建议是给一个 7 天方案对应“小k准备在 n 天内完成训练计划”这种思路天数任务目标第1天01-04题掌握 cout/printf 基本输出与格式化控制第2天05-06题练熟 scanf 多类型读入与多种格式输出第3天07-09题图形输出的规律观察与直接输出实现第4天10题转义字符大扫除超级玛丽游戏全文输出第5天11题数学建模 浮点数精度控制第6天从头重写全部题目用循环 数组的方式重构实现第7天随机抽 5 题限时完成检验是否真的掌握了而不是背答案第 6 天的“重写”是最关键的一步。你第一遍可能是照猫画虎写出来的隔几天再写一遍才能检验自己是真的理解了还是仅仅记住了。这个“隔几天重写”的训练方式在后面的算法学习中会反复用到从 1.1 就开始养成受益整个竞赛生涯。4. 我踩过的坑与排查技巧——常见问题速查4.1 编译不过的经典原因入门阶段 90% 的编译错误都出在这几个地方第一中英文标点混用比如把分号;打成中文分号报错信息在行尾那个瞬间很多人根本反应不过来第二头文件写错#include cstdio漏了尖括号或者写成#include cstdio第三main函数返回类型写成void main()——这在某些编译器下能过但在 NOI 标准环境下不保证统一写int main()加return 0;。遇到编译错误时别慌先看编译器指出的第一个错误位置不要顺着往下看因为 C 编译器经常“一错连环报”。改完一个错误再重新编译你会发现后面的错误往往自动消失了。这个经验听起来很基础但我在带学生的过程中至少有三分之一的人卡在编译错误上超过半小时就是因为他们一口气改了十处结果越改越乱。4.2 输出格式错误与 Presentation Error 的排查PEPresentation Error是 OJ 上最让人抓狂的判定结果你的答案和标准答案“看起来一样”但机器认为格式不对。常见原因包括行尾多了一个空格、少了一个换行、空行数量不对、大小写不一致。排查 PE 我有一个固定流程把标准样例输出复制到一个文件里再把你程序的输出重定向到另一个文件然后用fcWindows或diffLinux/Mac比对。如果本地比对完全一致但还是 PE那大概率是题目有特殊输出要求比如最后一行的换行问题这时候就盯着题目描述里的“输出格式”段落逐字读三遍。我见过最离谱的一次是一个题要求两个数字之间用“逗号空格”分隔结果我全程只看到了“逗号”两个字忽略了对空格的要求——这种失误就属于典型的“读题不细”跟能力无关但最亏。4.3 字符输入陷阱那个“吃”掉换行符的 scanf还有一个 1.1 章节里埋得最深的坑使用scanf(%c, c)读取字符时它会把输入流里残留的换行符读走。比如题目要求先输入一个整数再输入一个字符int n; char c; scanf(%d, n); scanf(%c, c); // 这里读到的可能是换行符而不是你想要的字符第二个scanf会直接把第一个输入结束后残留的\n读进c导致你的程序“看起来完全没收到字符输入”。解决办法有三种第一种是在%c前面加一个空格写成scanf( %c, c)这个空格会让scanf跳过所有空白字符第二种是在两个scanf之间加一句getchar();把换行符吞掉第三种是用cin cC 的提取运算符会自动跳过空白字符没有这个问题。我当年被这个坑折磨了整整一个晚上后来把原因研究透了才发现它本质上是一个 C 语言历史遗留设计scanf的%c不会跳过空白是为了满足“精确读取每个字符”的需求。理解了这个设计意图你以后就不会再记混了。顺便说一下如果题目要求读入的字符串里可能含有空格比如“输入一行字符串里面可能包含空格”那scanf(%s)也行不通了得用fgets或getline——这些是后面章节的内容但在 1.1 提前意识到能帮你省不少事。4.4 转义字符大坑超级玛丽游戏教会我的事1.1 里有一道 10 题“超级玛丽游戏”要求原样输出一大段字符画里面包含反斜杠\、双引号、单引号等特殊字符。很多人在这道题上反复 CE编译错误就是因为在字符串里直接写了反斜杠而 C 看来\是转义字符的开始。举几个必须背下来的转义写法想输出的字符代码写法说明反斜杠\\\双写反斜杠双引号\反斜杠双引号单引号\反斜杠单引号换行\n常用Tab 制表符\t输出水平制表输出超级玛丽这道题时最稳妥的做法是把字符画原样保存到记事本然后一行一行用printf(...);包起来凡是看到\、、这三个字符就手动加转义。这个过程无聊且机械但做完之后你对转义字符的记忆会牢固到想忘都忘不掉。我自己刷这道题的时候是拿着题目原文一个个字符对照着改的总共花了快一个小时。但那次之后C 字符串里哪些字符需要转义我再也没有搞混过。5. 把1.1的经验变成你自己的东西写到这里如果你已经把这 20 来道题全都刷完了一遍恭喜你你的信息学竞赛之路算是正式起步了。但我更想说的是刷完题只是第一步比刷题更重要的是你从这组题里带走什么。第一个要带走的是“格式敏感度”。从现在开始你每次写输出代码都先问自己三个问题我的输出有没有多余的空格行尾有没有多余的换行大小写和题目样例一致吗这三个问题养成习惯一年后你会感激自己。第二个要带走的是“拿纸笔先算再敲代码”的习惯。地球人口承载力那道题几乎是我见过所有入门选手第一次遇到“数学建模”的地方。遇到这类题最忌讳的就是开电脑就敲代码边敲边想。正确姿势是先在草稿纸上把变量设好把等式列出来推导出最终公式再打开编辑器写代码。第三个要带走的是“重写”的习惯。第 6 天把题目重写一遍这个建议是我反复向学生强调的。第一遍写代码你是在“读懂别人的思路”第二遍写代码你才是在“调用自己的思路”。这个差距决定了一个人究竟是在学编程还是只是在抄代码。根据我个人的经验能认认真真把 NOI 题库 1.1 全题解琢磨透的人后面学 1.2、1.3、1.5 的速度会明显比其他同学快一截。原因很简单信息学竞赛里最废时间的从来不是算法本身而是“程序跑不过去但你不知道为什么”的漫长调试。1.1 这章把最常见的调试场景都给你预演了一遍你提前踩过这些坑后面就能少流很多汗。现在打开题库从第一题开始把这个地基打得扎实一点吧。本文还有配套的精品资源点击获取