
简介这份资源面向正在刷北大POJ、准备ACM/ICPC入门或巩固算法基础的编程学习者收录了从1000到3673区间内大量经典题目的可运行答案覆盖模拟、枚举、数论、动态规划、图论、贪心、搜索等常见考点适合作为日常练习对照与思路参考。压缩包为rar格式共157个文件其中156个cpp源码文件和1个txt说明文件整体仅59KB轻量易存cpp文件可直接编译运行便于逐题调试与验证。目前已有2653人学习下载说明其在POJ题解类资源中具有一定认可度。读者可借此快速定位题目实现方案对照源码理解边界处理、输入输出格式与算法选择尤其适合在卡题时参考不同解法或按题号顺序系统刷题、查漏补缺逐步建立自己的解题模板与调试习惯。1. 从 POJ 基础题说起为什么刷完 100 道还是不会写代码很多人第一次打开 POJPKU Online Judge时看到 1000 多道题号第一反应是“从 1000 开始顺着刷”。我当年也这么干过结果刷到 1010 附近就卡住了——不是题难是根本不知道自己写的代码为什么能过、为什么超时。POJ 的部分基础题目答案网上流传的版本很多但真正有价值的是理解每道题背后的输入输出模型、边界条件和算法选择逻辑。POJ 的经典基础题集中在 1000-1500 区间覆盖 AB、高精度、枚举、简单动态规划、字符串处理这几类。适合刚学完 C/C 语法、想通过在线评测系统验证自己代码正确性的同学也适合准备算法面试但需要快速找回手感的人。这一篇不讲虚的直接按题型拆解把每道典型题的代码、参数、坑点讲清楚让你能照着复现也能看懂为什么这么写。2. POJ 基础题的四类核心模型与选型逻辑2.1 输入输出模型POJ 的“黑匣子”规则POJ 的评测机制是标准的黑匣子你提交代码系统用预设的输入文件跑你的程序比对输出。它不关心你的代码风格只看结果。这意味着两件事第一输入格式必须严格匹配题目描述多一个空格、少一个换行都可能 WAWrong Answer第二输出格式必须完全一致包括行末换行和空格。常见做法是先用scanf/printf或cin/cout读入但要注意 POJ 早期题目对cin的性能不友好数据量大时容易 TLETime Limit Exceeded。我一般会先看题目数据范围如果 n 超过 10^5果断换scanf。以 POJ 1000 为例题目要求读入两个整数 a 和 b输出 ab。代码简单到不能再简单但新手常犯的错是忘了return 0或者用了void main。POJ 的编译器是 GCCvoid main会直接编译错误。#include stdio.h int main() { int a, b; // 读入两个整数scanf 返回成功读入的变量个数 while (scanf(%d %d, a, b) ! EOF) { printf(%d\n, a b); // 每个结果独占一行 } return 0; }这段代码的关键在于while (scanf(...) ! EOF)。POJ 的输入文件可能包含多组测试数据直到文件结束。如果你只写一次scanf遇到多组数据就会漏掉后面的。参数说明%d对应inta取地址EOF是文件结束标志。逻辑上每次循环读两个数输出和再换行。注意printf里的\n不能省否则所有结果会挤在一行直接 WA。2.2 高精度运算当long long也装不下时POJ 1503 是典型的高精度加法输入两个不超过 100 位的正整数求和。long long最多存 19 位100 位必须用数组模拟。常见做法是用字符数组读入转成整数数组逆序存储然后逐位相加、处理进位。#include stdio.h #include string.h #define MAX 200 int main() { char s1[MAX], s2[MAX]; int a[MAX] {0}, b[MAX] {0}, sum[MAX] {0}; scanf(%s %s, s1, s2); int len1 strlen(s1), len2 strlen(s2); // 逆序存入数组个位在 a[0] for (int i 0; i len1; i) a[i] s1[len1 - 1 - i] - 0; for (int i 0; i len2; i) b[i] s2[len2 - 1 - i] - 0; int len len1 len2 ? len1 : len2; int carry 0; for (int i 0; i len; i) { sum[i] a[i] b[i] carry; carry sum[i] / 10; // 进位 sum[i] % 10; // 当前位 } if (carry) sum[len] carry; // 最高位进位 for (int i len - 1; i 0; i--) printf(%d, sum[i]); printf(\n); return 0; }参数说明MAX设为 200 足够 100 位加法。a[i] s1[len1-1-i] - 0把字符转成数字逆序是为了让个位对齐。carry保存进位sum[i] % 10保留当前位。最后从高位到低位输出。坑点如果最高位有进位必须扩展长度否则结果少一位。我见过有人忘了这一步结果 991 输出 00。2.3 枚举与模拟POJ 1013 的“称硬币”怎么不超时POJ 1013 是道经典模拟题12 枚硬币有一枚假币重量可能轻可能重给三次称量结果判断哪枚是假币以及轻重。新手容易写成暴力枚举所有可能但 12 枚硬币 × 2 种状态 24 种情况每种情况验证三次称量计算量很小完全不会超时。关键是把称量结果抽象成字符串比较。#include stdio.h #include string.h char left[3][10], right[3][10], result[3][10]; // 判断硬币 c 是否为假币heavy 为 1 表示重0 表示轻 int is_fake(char c, int heavy) { for (int i 0; i 3; i) { int l 0, r 0; // 统计左边和右边假币的“重量贡献” for (int j 0; left[i][j]; j) { if (left[i][j] c) l heavy ? 1 : -1; } for (int j 0; right[i][j]; j) { if (right[i][j] c) r heavy ? 1 : -1; } // 根据称量结果判断是否矛盾 if (l r) { if (strcmp(result[i], even) ! 0) return 0; } else if (l r) { if (strcmp(result[i], up) ! 0) return 0; } else { if (strcmp(result[i], down) ! 0) return 0; } } return 1; } int main() { int n; scanf(%d, n); while (n--) { for (int i 0; i 3; i) { scanf(%s %s %s, left[i], right[i], result[i]); } for (char c A; c L; c) { if (is_fake(c, 1)) { printf(%c is the counterfeit coin and it is heavy.\n, c); break; } if (is_fake(c, 0)) { printf(%c is the counterfeit coin and it is light.\n, c); break; } } } return 0; }逻辑说明is_fake函数模拟三次称量。如果假币重放在左边则左边下沉up放在右边则右边下沉down。l和r分别表示左右两边假币的贡献值。如果l r说明两边平衡结果必须是even如果l r左边重结果必须是up否则down。参数heavy控制假币是重还是轻。坑点result字符串是up、down、even注意大小写和拼写POJ 对字符串匹配严格。2.4 简单动态规划POJ 1163 数塔的递推写法POJ 1163 是数塔问题从塔顶走到塔底每次只能走左下或右下求路径最大和。这是最基础的 DP 入门题。常见做法是自底向上递推把二维数组压缩成一维。#include stdio.h #define MAX 100 int main() { int n; int a[MAX][MAX]; scanf(%d, n); for (int i 0; i n; i) { for (int j 0; j i; j) { scanf(%d, a[i][j]); } } // 自底向上从倒数第二行开始 for (int i n - 2; i 0; i--) { for (int j 0; j i; j) { // 当前节点加上下方两个子节点的较大值 a[i][j] (a[i1][j] a[i1][j1]) ? a[i1][j] : a[i1][j1]; } } printf(%d\n, a[0][0]); return 0; }参数说明a[i][j]存储数塔第 i 行第 j 列的值。递推公式a[i][j] max(a[i1][j], a[i1][j1])表示从下往上累加。最后a[0][0]就是最大路径和。坑点数组大小要开够POJ 1163 的 n 最大 100MAX设 100 刚好但建议多开 5 个防越界。另外输入是逐行读入每行数字个数等于行号1别读错。3. 避坑与排查POJ 提交后 WA/TLE 的 5 个血泪教训3.1 现象本地跑得好好的提交就 WA原因POJ 的测试数据可能包含多组输入而你的代码只处理了一组。比如 POJ 1000 的输入文件里其实有多组 ab如果你只写一次scanf后面的数据没读输出自然不对。解决用while (scanf(...) ! EOF)或while (cin ...)循环读入直到文件结束。3.2 现象输出结果和样例一模一样还是 WA原因行末多了空格或者少了换行。POJ 的比对是逐字节的多一个空格就判错。比如 POJ 1013 的输出格式是A is the counterfeit coin and it is heavy.句号后面不能有空格但句号前必须有空格。解决把样例输出复制到代码里逐字符比对特别注意\n和空格的位置。3.3 现象TLE但算法明明是对的原因用了cin/cout且数据量超过 10^5或者循环里重复计算。POJ 的服务器较老cin默认与stdio同步速度慢。解决在main开头加ios::sync_with_stdio(false); cin.tie(0);或者直接换scanf/printf。另外检查是否有不必要的嵌套循环比如在循环里调用strlen。3.4 现象数组越界导致 RERuntime Error原因数组开小了或者循环边界写错。比如 POJ 1503 的高精度加法如果MAX设 100但输入正好 100 位加上进位可能到 101 位就越界了。解决数组大小比题目上限多开 5-10 个。循环边界用i len而不是i len除非你明确知道要处理第 len 个元素。3.5 现象浮点数比较出错WA 得莫名其妙原因POJ 有些题涉及浮点数比如求面积、平均值直接用比较浮点数会因精度问题出错。解决用fabs(a - b) 1e-6判断相等。输出时注意题目要求保留几位小数用printf(%.2f\n, ans)控制格式。如果题目说“四舍五入”printf默认就是四舍五入但要注意浮点数本身的误差。4. 从 AC 到举一反三把 POJ 基础题变成自己的算法肌肉刷 POJ 基础题的目的不是记住答案而是把输入输出、边界处理、算法选择变成条件反射。我自己的习惯是每道题 AC 之后把代码里的关键参数改一改比如把高精度加法的MAX从 200 改成 50看看会不会 RE把数塔的递推方向从自底向上改成自顶向下看看结果是否一致。这种“折腾”能让你真正理解每行代码的作用。进阶用法上可以尝试用同一道题练不同语言。比如 POJ 1000 用 C 写一遍再用 Python 写一遍对比scanf和input().split()的差异。Python 在 POJ 上提交要注意版本POJ 支持 Python 2.7 和 3.x但有些题用 Python 会 TLE因为常数大。这时候可以练手写快速 IOimport sys def main(): # 一次性读入所有输入按空白分割 data sys.stdin.read().split() # 每两个一组求和 for i in range(0, len(data), 2): a int(data[i]) b int(data[i1]) print(a b) if __name__ __main__: main()这段 Python 代码用sys.stdin.read()一次性读入比input()循环快很多。参数说明split()默认按空白字符分割包括空格和换行。range(0, len(data), 2)每次跳两个因为输入是成对的。坑点如果输入数据量极大read()会占用较多内存但 POJ 基础题的数据量通常不大够用。另一个技巧是建立自己的“错题本”。每次 WA 或 TLE记录三件事题目编号、错误类型、修正方法。比如“POJ 1503WA原因最高位进位没处理修正if (carry) sum[len] carry;”。积累多了你会发现 POJ 基础题的坑就那几类多组输入、行末格式、数组越界、精度问题、性能瓶颈。把这些坑填平再刷难题时就能少走弯路。最后说个我自己的教训早年刷 POJ 时我总想“这题我会了跳过”结果遇到变体题还是卡壳。后来强迫自己每道基础题都手写一遍不复制粘贴哪怕是最简单的 AB。手写的过程会暴露很多细节问题比如scanf的忘了写、printf的%d写成了%f。这些低级错误在真实面试或工作中是致命的。希望帮到你。本文还有配套的精品资源点击获取