ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

程序设计基础OJ刷题指南:高频考点、易错点与答题节奏

程序设计基础OJ刷题指南:高频考点、易错点与答题节奏

简介:这份资源是面向计算机专业初学者与编程入门学习者的程序设计基础 OJ 题库合集,源自南京信息工程大学(NUIST)的在线评测平台,可用于系统训练编程语法、算法设计与数据结构应用能力。压缩包整体约 482.72MB,涵盖排序、搜索、图论、动态规划等经典算法题目及配套练习素材,适合课后刷题、课程实验与算法能力进阶。已有 754 人学习下载,说明其在同类入门题库中具备一定参考价值。读者可借助题库按难度梯度反复练习,通过提交代码获得实时评测反馈,快速定位逻辑错误与复杂度问题;同时可结合数组、链表、栈、队列、树、哈希表等数据结构题目,理解算法与数据组织的配合方式,逐步培养将复杂问题拆解为可编码子任务的能力,为后续软件开发与算法竞赛打下扎实基础。

1. 从一道“看着会、写出来全错”的题说起

程序设计基础这门课的 OJ 题库,最容易让人翻车的不是难题,而是那种题干三行、样例两组、你觉得自己十分钟能秒掉的题。我见过太多人打开编译器就开始敲,循环边界随手一写,提交之后红了一片,改来改去反而越改越乱。这场考试考的不是你会不会写for,而是你能不能在有限时间里把题意翻译成正确的边界、正确的数据类型、正确的输出格式。拿分的关键只有一句话:先把输入输出和边界想清楚,再动手。这份题库适合正在准备程序设计基础机考、课程 OJ 刷题、以及需要靠刷题稳住基础分的人,下面按考点分布、高频题型、易错点和答题节奏一层层拆开讲。

2. 考点分布:程序设计基础 OJ 到底在考哪几类题

2.1 输入输出与格式题:最容易丢冤枉分的一类

OJ 题库里有一类题,算法难度几乎为零,但通过率并不高,原因全在输入输出格式。常见形态包括:多组测试数据直到文件结束、第一行给测试组数、每组数据之间要求空行、输出保留固定小数位、行末不能有多余空格。这类题在程序设计基础阶段占比不低,因为它考的是你读题是否仔细、是否理解scanf返回值和while循环的配合。

以“多组输入求和”为例,标准写法是这样的:

#include <stdio.h> int main() { int a, b; // scanf 返回成功读入的变量个数,读到文件末尾返回 EOF while (scanf("%d %d", &a, &b) != EOF) { printf("%d\n", a + b); } return 0; }

这段代码的关键在!= EOF这个判断。很多人写成while (scanf("%d %d", &a, &b)),当输入里出现 0 0 时循环会提前退出,样例能过、隐藏用例全挂。参数上要注意:scanf的返回值是成功赋值的变量个数,不是读到的字符数;如果题目说“输入以 0 0 结束”,那判断条件要改成读入后检查a == 0 && b == 0再break,两种结束方式不能混用。

再比如保留小数位的题,printf("%.2f", x)默认是四舍五入,但有些题目要求“向下取整到两位”,那就不能直接靠格式符,要先做数值处理。这类细节在题库里反复出现,属于典型的“会写但写不对”。

2.2 循环与枚举题:边界写错就全盘皆输

循环题是程序设计基础的骨架,题库里大量题目围绕“求范围内满足条件的数”“打印图形”“累加累乘”展开。这类题的共同陷阱是边界:从 0 开始还是从 1 开始、包不包含端点、循环变量用int还是long long。

看一道典型题:求 1 到 n 之间所有偶数的和。

#include <stdio.h> int main() { int n; long long sum = 0; // 累加结果可能超出 int 范围 scanf("%d", &n); for (int i = 2; i <= n; i += 2) { // 从 2 开始,包含 n sum += i; } printf("%lld\n", sum); return 0; }

这里有两个参数值得说。第一,sum用long long,因为 n 较大时累加会溢出,int大约只能存到二十多亿,题库里经常用 n 接近上限的数据来卡这一点。第二,循环条件i <= n而不是i < n,题目说“1 到 n 之间”通常包含 n,如果 n 是奇数,最后一个偶数仍然小于 n,边界不影响结果,但 n 是偶数时差一个数就是答案错误。这类题面试官或出题人最想看你有没有“先确认端点”的习惯。

图形打印题则是另一类高频题,比如打印直角三角形、菱形、九九乘法表。它们的得分点不在算法,而在每行空格数和星号数的推导。建议在纸上先写出前三行的数量关系,再翻译成循环,不要凭感觉写for嵌套。

2.3 数组与字符串题:下标越界和结束符是重灾区

数组题在题库里通常以“统计”“查找”“排序”“逆序”形式出现。字符串题则围绕长度、比较、字符统计展开。这一类题的高频失分点非常集中:数组开小了、下标从 1 开始时忘了留位置、字符串忘了\0、用strlen却包含了不该包含的字符。

以“统计字符串中大写字母个数”为例:

#include <stdio.h> #include <string.h> int main() { char s[105]; // 题目若说长度不超过 100,开到 105 留余量 int count = 0; scanf("%s", s); // %s 遇到空白停止,适合无空格字符串 for (int i = 0; i < strlen(s); i++) { if (s[i] >= 'A' && s[i] <= 'Z') { count++; } } printf("%d\n", count); return 0; }

参数说明:数组长度要比题目给的上限多开几个,防止结束符和边界数据把程序写崩;scanf("%s")不适合含空格的输入,遇到整行读取要用fgets。另外,循环里反复调用strlen在数据量大时会拖慢程序,虽然基础题一般不卡这个,但养成先存长度的习惯没坏处。这类题在 OJ 上提交后如果提示“运行时错误”,第一反应就该去查数组大小和下标。

3. 高频考点:五类必刷题型和答题模板

3.1 排序与查找:手写冒号排序的得分点在哪

程序设计基础阶段的排序题,通常不要求你用库函数,而是让你手写冒泡或选择排序。出题人想看的不是效率,而是你对双重循环和交换逻辑的掌握。答题模板可以固定成两层循环加一个临时变量,外层控制轮数,内层控制比较范围。

// 冒泡排序:升序 for (int i = 0; i < n - 1; i++) { for (int j = 0; j < n - 1 - i; j++) { if (a[j] > a[j + 1]) { int t = a[j]; a[j] = a[j + 1]; a[j + 1] = t; } } }

内层循环的终点是n - 1 - i,因为每轮结束后末尾已经有序,再比较就是浪费。很多考生写成j < n - 1,结果也能过,但多做了无效比较;更危险的是写成j <= n - 1,直接越界。查找题则常考顺序查找和二分查找,二分查找的模板要背熟left <= right和mid = (left + right) / 2,注意mid的更新是left = mid + 1或right = mid - 1,写成left = mid会死循环。

3.2 递归与函数题:出口写不对,栈就爆了

递归题在基础题库里一般不难,典型如阶乘、斐波那契、求最大公约数。它们的共同得分点是“先写出口,再写递推”。以斐波那契为例:

int fib(int n) { if (n == 1 || n == 2) return 1; // 出口必须放在最前面 return fib(n - 1) + fib(n - 2); }

出口条件写错是这类题的第一大失分点,比如把n == 1写成n == 0,或者忘了处理 n 为 0 的情况。第二个失分点是递归层数太深导致栈溢出,题库里如果 n 给到 40 以上,朴素递归会明显变慢,这时候要么加记忆化,要么改用循环。面试官问递归题时,最想听你先说出口、再说递推关系、最后说复杂度,这三句话顺序不能乱。

3.3 素数判断与数论小题:从 2 到根号 n 的循环怎么写

素数判断题几乎每套基础题库都有,标准写法是试除到平方根:

int isPrime(int n) { if (n < 2) return 0; // 小于 2 不是素数 for (int i = 2; i * i <= n; i++) { if (n % i == 0) return 0; } return 1; }

循环条件用i * i <= n而不是i <= sqrt(n),前者避免浮点误差,也少一个头文件依赖。常见错误是漏掉n < 2的判断,导致 1 被当成素数;或者循环写成i < n,效率低但结果对,遇到大数会超时。这类题还会延伸出“统计范围内素数个数”“分解质因数”,核心都是同一个循环骨架。

3.4 模拟题:把生活规则翻译成代码

模拟题是 OJ 题库里区分度较高的一类,题干往往描述一个规则,比如“排队打水”“成绩等级转换”“日期推算”。这类题没有现成算法套,考的是你能不能把文字规则拆成顺序、分支和循环。答题时建议先在草稿上列出所有状态和转换条件,再写代码。

以成绩等级转换为例,规则是 90 以上 A、80 到 89 为 B、60 到 79 为 C、60 以下 D:

if (score >= 90) printf("A\n"); else if (score >= 80) printf("B\n"); else if (score >= 60) printf("C\n"); else printf("D\n");

这里的关键是条件顺序,从高到低写可以省去上界判断。如果反过来从低到高写,每个分支都要写双条件,容易漏。模拟题最怕的是“样例过了但隐藏用例错”,通常是因为没考虑边界值,比如正好 90、正好 60。答题时把边界值单独列出来测一遍,能挡掉大部分翻车。

3.5 简单数据结构:栈和队列的手写实现

基础题库里栈和队列一般以“括号匹配”“进制转换”“约瑟夫环”形式出现。手写栈的核心是一个数组加一个栈顶指针:

int stack[1005]; int top = -1; // 栈空时 top 为 -1 void push(int x) { stack[++top] = x; } int pop() { return stack[top--]; } int empty() { return top == -1; }

参数上要注意栈顶指针的初始值和入栈出栈的先后顺序,++top是先加再用,top--是先用再减,写反了就会覆盖数据或读到脏值。队列则常用数组加头尾指针,或者循环队列。这类题面试官常追问“栈空了再弹出会怎样”,标准答法是先判空再操作,代码里加if (!empty())保护。

4. 易错点:这五类题丢分最多,逐条对照改

4.1 多组输入写成单组,样例过隐藏挂

错在哪:题目要求“多组数据”,考生只写了一次scanf,本地用一组样例测试通过,提交后只过第一个测试点。为什么错:没有识别题干里“多组”“直到输入结束”这类关键词,或者不知道EOF的用法。怎么答对:看到“多组”就用while (scanf(...) != EOF),看到“第一行是组数”就先读T再套while (T--),两种模式在草稿上先标出来再写代码。

4.2 整数溢出,累加结果变负数

错在哪:求和、阶乘、斐波那契这类题用int存结果,数据一大就变成负数或错误值。为什么错:对int的范围没有概念,默认“数字不大”。怎么答对:凡是累加、累乘、斐波那契,先估算最大值,超过二十亿就用long long,输出格式同步改成%lld。这类题在题库里专门用大数据卡人,属于血泪经验级别的坑。

4.3 数组开小一位,结束符没地方放

错在哪:题目说字符串长度不超过 100,考生开char s[100],结果最后一个字符加\0越界。为什么错:忽略了 C 语言字符串以\0结尾,需要额外一个位置。怎么答对:数组长度一律比题目上限多开 5 到 10,字符串题尤其如此;提交后如果报运行时错误,先查数组尺寸。

4.4 循环边界差一,端点值全错

错在哪:for (int i = 1; i < n; i++)和i <= n混用,导致少算一个数或多算一个数。为什么错:读题时没确认“到 n”是否包含 n,写代码时凭手感。怎么答对:动笔前在草稿上写一行“范围:1 到 n,包含端点”,循环条件照着这行写;写完用 n=1 和 n=2 两个最小用例手动跑一遍。

4.5 输出格式多空格少换行,被判格式错误

错在哪:行末多打一个空格,或者每组数据之间忘了空行,OJ 返回“格式错误”而不是“答案错误”。为什么错:只关注数值对不对,没看输出要求。怎么答对:把题目的输出样例逐字符对照,特别注意“每组之间空一行”和“行末无空格”这类描述;不确定时宁可严格照样例,不要自己加装饰。

5. 答题节奏:从读题到提交的五步固定动作

5.1 读题三遍,先标输入输出再想算法

第一遍读题意,第二遍圈出输入格式和输出格式,第三遍确认数据范围和边界词。很多翻车不是不会写,而是读题时漏了“多组”“保留两位”“升序”这些限定词。我的习惯是读完题先在草稿左上角写三行:输入是什么、输出是什么、范围多大。这三行写完,算法方向基本就定了,写代码时也不会跑偏。

5.2 先写框架再填逻辑,编译通过再测样例

不要一上来就写完整逻辑。先把#include、main、输入、输出框架搭好,编译一次确认没语法错误,再往中间填循环和判断。这样做的好处是语法错误和逻辑错误分开排查,不会在一堆报错里迷失。样例测试通过后,别急着提交,自己再构造两组边界数据,比如最小值、最大值、刚好等于端点的值。

5.3 提交失败先看错误类型,再定位代码

OJ 的判题结果是有信息量的:答案错误通常是逻辑或边界问题,运行时错误多半是数组越界或除零,超时是复杂度或死循环,格式错误是输出细节。看到结果先对号入座,不要盲目改代码。比如运行时错误,第一反应查数组大小和指针;超时先看有没有双重循环可以优化,或者循环条件是不是写成了死循环。

5.4 卡题超过十五分钟就换题,回头再啃

机考时间有限,一道题卡太久会拖垮整场节奏。我的做法是十五分钟没有明确思路就先跳过,把能拿的分先拿到,回头再处理。很多题换个时间看,思路反而通了。这个习惯听起来简单,但真正在考场上做到的人不多,属于典型的后悔药——提前准备好,比事后懊恼有用。

5.5 最后十分钟专查边界和格式

交卷前留十分钟,不写新题,只做两件事:把所有已写题的边界值再想一遍,把所有输出格式再对一遍样例。这两件事能捞回的分,往往比再啃一道难题多。从那以后我每次进考场都强制走一遍这个五步流程,读题标三行、框架先编译、失败看类型、卡题就跳过、最后查边界,希望帮到你。

本文还有配套的精品资源,点击获取

返回列表