
简介针对NOI题库OpenJudge1.1「编程基础之输入输出」章节的题解资料面向信息学竞赛入门者与正在刷OpenJudge的C初学者。压缩包内共10个cpp源文件整体仅4KB每个文件对应一道题的完整AC代码覆盖从Hello World、整数与浮点数输出、保留小数位、对齐输出到字符三角形/菱形、超级玛丽游戏等典型输入输出练习代码短小直接便于逐题对照学习。已有5107人学习/下载是一份高频使用的入门参考资料。读者可将每份代码作为正确性基准用于自查输出格式、精度控制与字符图形构造等常见易错点小巧的体积也方便拷贝到本地或在线评测环境中反复验证。所有源码按题号命名结构清晰每份均可单独编译运行适合入门阶段先做题再对照也便于教师布置作业或备赛复习时快速取用。 做NOI题库的朋友应该对“1.1 编程基础之输入输出”这章不陌生。我最初刷这章的时候只花了一个晚上就把所有题AC了心里还觉得“就这”。结果后来参加了一次校内模拟赛在输出格式上被扣了20分才意识到1.1的价值根本不是“让我会写Hello World”而是“让我知道评测机眼里什么才是对的”。这篇题解我会按1.1全题列表逐题说明思路再把我踩过的坑单独拉出来聊一聊希望能帮你把基础打扎实。1. 先说清楚1.1这章到底在练什么1.1 题目清单与考察点1.1是整套NOI题库的起点标题是“编程基础之输入输出”。它不考算法不考数据结构和数学只考察一件事你能不能把程序输出得和题目要求完全一致。下面是我整理的这个章节的常见题目清单以OpenJudge NOI题库为准不同平台上顺序可能稍有调整但考察点基本一致。编号题目核心考察点01Hello, World!基本输出、无多余字符02输出第二个整数输入三个整数、输出第二个03对齐输出格式化输出、右对齐、宽度控制04输出保留3位小数的浮点数浮点数格式化05输出浮点数直接输出、保留合理精度06空格分隔输出按要求用空格连接多个输出项07输出字符菱形字符图形、循环嵌套08字符三角形字符图形、循环规律09字符菱形与07类似格式要求更严格10超级玛丽游戏无输入输出一个多行字符画如果你用的是其他版本可能还会碰到“字符直角三角”“数字三角形”之类本质都是一样的用最少的状态变量描述清楚每一行、每一列的输出内容。这章的题目数量不多但每道都在反复提醒你一个核心准则信息学竞赛不是“看起来对”而是“必须和标准输出逐字节一致”。多一个空格、少一个换行、全角标点混入半角字符串都会直接判错没有中间地带。1.2 为什么简单题反而最致命很多刚入门的朋友喜欢把“输出题”和“白给题”划等号但我看过的错误提交里死于输出的比例远超想象。常见情况有题目要求两个单词之间一个空格你多打了两个该在行尾换行的地方没换行或者多输出一个空行使用cin/cout频繁刷新缓冲在后续大量输出时变慢浮点数输出时没有控制小数位数默认6位和要求的3位不一致。这些问题在1.1阶段暴露出来其实是好事。因为到了后面的题目评测机可不会因为你“思路对”就通融。理解这一点比AC这十道题本身更重要。2. 逐个击破每道题的思路与参考代码2.1 01~02题Hello World与第二个整数第一题就是输出“Hello, World!”注意大小写和逗号。代码非常简单#include cstdio int main() { printf(Hello, World!\n); return 0; }第二题读入三个整数输出第二个整数。注意变量接收顺序#include cstdio int main() { int a, b, c; scanf(%d%d%d, a, b, c); printf(%d\n, b); return 0; }为什么我在这两题就推荐你用scanf/printf而不是cin/cout因为从1.1阶段就要养成习惯NOI系列的评测环境对scanf/printf的掌控更直接格式化输出也更可控。cin/cout不是不能用但一旦题目让你按宽度补零、保留三位小数用printf会清爽得多。代码末尾的\n千万别省略。评测标准输出一般要求结尾有换行虽然不少评测系统会自动忽略文件末尾的换行但从一开始就不留隐患是最省事的做法。2.2 03~06题格式化输出四连第三题“对齐输出”通常要求读入整数、浮点数、字符之类的数据再按固定宽度右对齐输出。以三个整数为例#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右对齐。如果题目要求左对齐就写%-8d。关键是不要自己手打空格去“凑”宽度手打空格在处理多位数时会全部乱掉。第四题“输出保留3位小数的浮点数”考的是printf浮点数格式控制#include cstdio int main() { double x; scanf(%lf, x); printf(%.3f\n, x); return 0; }第五题“输出浮点数”如果题目没有特殊要求一般直接printf(%f)即可。这里有一个C语言新手最容易踩的坑double用scanf读入是%lf用printf输出则推荐%f。虽然C99后printf的%lf也能用但在一些老式评测环境下还是可能出问题建议按标准写法来。第六题“空格分隔输出”往往是一个字符、一个整数、一个浮点数输出时用空格分隔。关键点是%c读字符之前要加一个空格去吃掉缓冲区里的换行符#include cstdio int main() { char ch; int a; double b; scanf( %c%d%lf, ch, a, b); printf(%c %d %.6f\n, ch, a, b); return 0; }这里的scanf( %c%d%lf, ...)中%c前面的空格非常关键。没有它ch会读到上一次输入结束后的换行符程序看似没问题输出却会少一个字符。提示scanf的格式串里出现空格表示“跳过所有空白字符”。这是处理字符输入时的常用技巧。2.3 07~09题字符图形的循环规律这三道题本质是同一类按行输出字符。只要找到行号与空格数、字符数之间的关系代码并不复杂。比如“字符三角形”输入一个字符c输出由该字符组成的三角形可以用下面这个模板#include cstdio int main() { char c; scanf(%c, c); for (int i 1; i 3; i) { for (int j 1; j 3 - i; j) printf( ); for (int j 1; j 2 * i - 1; j) printf(%c, c); printf(\n); } return 0; }如果你需要输出五行的字符菱形比如“输出字符菱形”那题思路也一样先输出上半部分的递增行再输出下半部分的递减行。菱形上半部分三行下半部分两行#include cstdio int main() { char c; scanf(%c, c); for (int i 1; i 3; i) { for (int j 1; j 3 - i; j) printf( ); for (int j 1; j 2 * i - 1; j) printf(%c, c); printf(\n); } for (int i 2; i 1; i--) { for (int j 1; j 3 - i; j) printf( ); for (int j 1; j 2 * i - 1; j) printf(%c, c); printf(\n); } return 0; }这类题看起来不涉及算法却非常锻炼“用变量描述重复结构”的能力。你会慢慢发现后面做动态规划、字符串处理时很多二维状态转移的思路本质上和这种“行、列、对称”的模型一脉相承。2.4 第10题超级玛丽游戏“超级玛丽游戏”这题没有输入只要求原样输出一大段字符画。我在初学时想自己手敲结果卡了很久不是这里少个点就是那里多个空格。最稳妥的方法是直接复制题目描述中给出的字符画作为多行字符串输出。C代码的整体结构是#include cstdio int main() { printf( ********\n); // 中间省略按题目给定字符画逐行输出 return 0; }这题的考点主要是耐心和细心。如果字符画里面包含反斜杠或单引号还要注意转义反斜杠本身要写成\\单引号要写成\。超码丽原题基本没有这个情况但养成“原样复制题目字符画”的意识能避免很多不必要的WA。3. 我踩过的坑1.1最容易翻车的五个瞬间3.1 浮点数“四舍五入”并不可靠C/C的printf在大多数环境下按四舍五入输出但浮点数在计算机里是二进制存储的很多十进制小数无法精确表示。比如0.105存进去可能是0.10499999...用%.2f输出时可能变成0.10而不是0.11。1.1阶段很少遇到这种极端情况但如果哪天题目加了“四舍五入”字样而printf又WA了可以试试在输出前加上一个很小的修正量比如x 1e-9再格式化。3.2 %c会“吃掉”换行符这是新手提问区最常出现的问题代码逻辑一眼看上去没问题输出结果却少了一个字符。排查到最后十有八九是scanf(%c, ch)读到了前面的回车。解决办法就是scanf( %c, ch)在%c前面加空格跳过空白。这个坑在“空格分隔输出”和“字符三角形”里几乎是必踩的。如果你发现自己的输出莫名其妙少东西先检查每一个%c之前有没有空格。3.3 行尾空格和多输出空行有些题目会明确说“行尾不要有多余空格”有些题目不说但评测数据里依然存在严格的逐字符比对。所以我在提交前总会习惯性检查循环输出的最后一个元素后面是不是又被代码多加了一个空格。比如输出一个数组下标里的值写成for (int i 0; i n; i) { if (i) printf( ); printf(%d, a[i]); }这类写法虽然不是1.1的内容但从第一道“空格分隔输出”开始养成“先判断是否需要分隔符”的习惯后面能少改很多代码。3.4 换行符到底要不要大部分题目的标准输出最后都带一个换行符这也是printf(...\n)的默认习惯。但有一类“字符画”题题面给的字符画最后一行没有换行如果你多输出一个空行可能就会被判错。我自己的经验是优先保证和题面给出的输出样例完全一致而不是自己主观加换行。如果不确定可以提交一次看评测结果再根据WA信息去判断。3.5 复制粘贴惹的祸字符串里的空格和标点必须和题面完全一致。很多人做“Hello, World!”时把英文逗号打成了中文逗号结果WA得莫名其妙。遇到这类“纯输出”题优先从题目描述里复制原文不要自己手打。这不是偷懒而是减少无谓错误的工程习惯。4. 刷完1.1之后把你的基础变成武器4.1 建立本机自测流程1.1的题目虽然简单但正好适合搭一套自测脚本。我常用的做法是把样例输入保存在in.txt把程序跑出来的结果重定向到out.txt再手动比对或使用diff命令。在命令行里执行g 1.1.cpp -o 1.1 ./1.1 in.txt out.txt然后对比out.txt和标准答案。有了这个习惯你不会再把“肉眼检查控制台输出”当成唯一的验证手段。后面题目复杂起来这个流程能帮你节省大量调试时间。4.2 先理解评测行为再谈优化1.1里没有时间限制压力所以很多人不会意识到“输出方式”也会影响效率。到了后续章节输入输出量变大cin/cout如果不关闭同步会明显变慢。我建议从1.1开始要么统一用scanf/printf要么在main开头加上ios::sync_with_stdio(false); cin.tie(0);虽然1.1题用不上但提前养成习惯可以少走弯路。同样的道理也适用于头文件不要每个文件都写上#include bits/stdc.h尽量只包含需要的内容。代码整洁度会影响你排查问题的速度。4.3 下一步怎么衔接完成1.1后题库的1.2到1.5通常开始涉及变量、顺序结构、选择结构和循环。你会发现1.2之后的题很多仍然在输出格式上做文章。如果你1.1的代码风格足够干净后面会轻松很多。我个人的建议是不要急着追求“一天刷完”而是每AC一道题就回头看看自己的代码里有没有多余的头文件、有没有可以更简洁的输出方式。这种打磨习惯长期来看比多刷十道题更有价值。我自己到现在写题时拿不准printf的格式控制符还会翻一翻当年的1.1代码。基础这东西真的越扎实越省时间。本文还有配套的精品资源点击获取