资讯动态

东方博宜OJ 1201-1210题解:C++基础算法详解与提交避坑指南

发布时间:2026/9/13 11:05:03 来源:尧图企业网站定制
东方博宜OJ的1201-1210是很多刚接触在线评测系统的同学都会搜的一个连续题号。我当初也搜过抄过不少代码但真正让我把这十题吃透的是后来一篇篇重新写、重新调的过程。这篇文章把我整理的1201-1210答案、每题的考点和一份可以直接交的C代码都放出来同时也会讲清楚每题背后的原理以及提交评测时最容易翻车的地方。不管你是急着交作业还是想把基础打牢都能从这里找到有用的东西。1. 先看这十题到底考什么考点分布与刷题顺序题号这个东西不同OJ之间经常对不上东方博宜OJ自己的题库顺序也不是永远固定。所以与其死记题号不如先认清1201-1210这十题在知识模块上到底覆盖了什么。我刷的时候整理过一张表方便你对号入座题号常见题目特征核心考点1201三个整数求最大值分支结构、条件比较1202求1到n的累加和for循环、数学公式1203判断某年是否为闰年逻辑运算符、优先级1204打印直角三角形星号图案循环嵌套、输出格式1205求斐波那契数列第n项递推、递归优化1206将数组元素逆序输出一维数组、倒序遍历1207统计字符串中大写字母个数字符串遍历、ASCII码1208求两个正整数最大公约数辗转相除法1209判断一个数是否为素数循环边界、平方根优化1210输出所有三位水仙花数拆位、枚举、数学运算如果你打开自己平台上的题库发现某个题号和这里对不上不用慌认准题目特征而不是死记编号。这十题整体偏基础但基础不等于简单很多人在1209、1210上第一次体会到“明明逻辑对提交却WA”的崩溃。1.1 从送分题到综合题的进阶逻辑前五题基本是单知识点后五题开始把多个知识点组合起来。1203考条件运算符的组合优先级1204考循环嵌套里的换行位置1208考数学算法1210考拆位运算。这些能力是后面刷排序、查找、模拟题的地基。我当时是先做一遍拿到AC再重新不看代码手写一遍两种感受完全不一样。手写一遍才会发现自己对for循环边界、数组下标这些细节到底有没有真懂。1.2 为什么我建议先自己写再对答案我知道搜“OJ答案”的大部分人就是想快速交作业这个我不反对但如果你想省事反而更应该先把题目复制出来自己跑一遍。哪怕写得很烂只要提交通过你至少知道了题目要求这时候再看下方的参考代码会明显看到自己的不足。直接抄代码的问题在于评测系统不会提醒你哪里没懂下次遇到类似题你还是只会复制粘贴。这十题我后来给其他同学讲的时候发现很多错误其实都出在“以为自己会了”的地方。2. 1201-1205题解分支、循环与数列这部分我把前五题的代码和思路拆开讲。代码用C写东方博宜OJ是支持这种写法的其他语言思路也一样把语法换掉就行。2.1 1201三个整数求最大值题目特征很直接给你三个整数让你输出其中最大的一个。常规做法是分支结构写起来就是两两比较。#include iostream using namespace std; int main() { int a, b, c; cin a b c; if (a b a c) { cout a endl; } else if (b a b c) { cout b endl; } else { cout c endl; } return 0; }如果你不想写这么长的逻辑直接用STL的max函数更省事#include iostream #include algorithm using namespace std; int main() { int a, b, c; cin a b c; cout max(a, max(b, c)) endl; return 0; }这里要注意的是比较运算符的等号。用还是对最终输出没有影响因为三个数相等时无论进入哪个分支输出的都一样。但如果你后面要处理“输出第几个数”这类问题等号处理就要小心。另外的优先级比||高如果加了括号更保险很多新手就是在这种地方漏括号导致逻辑混乱。2.2 1202求1到n的累加和这题本质是等差数列求和。你既可以写for循环从头加到尾也可以直接用数学公式n * (n 1) / 2。我推荐先把循环写熟因为后面很多题都需要循环思维。#include iostream using namespace std; int main() { int n; cin n; long long sum 0; for (int i 1; i n; i) { sum i; } cout sum endl; return 0; }为什么用long long而不是int因为n如果稍微大一点累加和很容易超过int的21亿上限。比如n等于70000结果已经突破24亿了。很多人在这种送分题上WA就是栽在数据类型上。如果你用公式法也要注意先把n强转成long long再乘避免两个int相乘时溢出。2.3 1203闰年判断闰年的定义是能被4整除但不能被100整除或者能被400整除。题目通常不会只给一个条件所以组合逻辑是这里的核心考点。#include iostream using namespace std; int main() { int year; cin year; if ((year % 4 0 year % 100 ! 0) || year % 400 0) { cout YES endl; } else { cout NO endl; } return 0; }%取余运算的优先级和、!这类比较运算符不太一样比较运算符又比、||高。为了避免踩坑最好把每个条件用括号包起来养成习惯。还有一个常见错误是只判断year % 4 0结果1900年这种年份就判断错了。1900能被4整除但不能被400整除所以不是闰年。2.4 1204打印直角三角形星号图案题目一般要求输入一个n输出n行星号第一行1个第二行2个以此类推。这题的考点是循环嵌套内层循环控制每行星号个数外层循环控制行数。#include iostream using namespace std; int main() { int n; cin n; for (int i 1; i n; i) { for (int j 1; j i; j) { cout *; } cout endl; } return 0; }最容易错的地方是把cout endl放在内层循环里那样每打一个星号就换一行图案全部乱掉。另外有些题目会要求靠右打印也就是前面加空格这时候内层要变成两个循环先打印空格再打印星号。你在OJ上看到“直角三角形”四个字时一定先看样例输出确定是左对齐还是右对齐。2.5 1205斐波那契数列第n项斐波那契数列从第1项开始通常是1、1、2、3、5、8……题目可能让你求第n项。网上很多教程喜欢用递归但递归在这个场景下效率很差计算第50项可能就卡住。用递推是最稳的。#include iostream using namespace std; int main() { int n; cin n; if (n 1 || n 2) { cout 1 endl; return 0; } long long a 1, b 1, c; for (int i 3; i n; i) { c a b; a b; b c; } cout c endl; return 0; }这题的考点不只是“知道递推公式”更关键的是理解滚动更新的过程每算出一个新数就把原来的第二项变成新的第一项把新数变成第二项。如果你直接写a b; b a b;会因为b被更新过导致结果错误。这种细节在初学阶段非常容易忽略。3. 1206-1210题解数组、字符串与数学思维后五题从单点知识变成了组合应用。数组、字符串、数学算法每个都是后面刷题的基本功。3.1 1206数组元素逆序输出题目一般先输入n再输入n个整数最后要求把这n个数逆序输出。最直观的方法是开一个新数组倒着存但完全不必要直接倒序遍历原数组即可。#include iostream using namespace std; int main() { int n; cin n; int a[105]; for (int i 0; i n; i) { cin a[i]; } for (int i n - 1; i 0; i--) { cout a[i] ; } cout endl; return 0; }数组长度我习惯开到105比题目给的上限多一点防止越界。逆序输出时最常犯的错是循环从i n开始把数组最后一个元素后面的垃圾值打出来。另外这里会在每个数后面输出一个空格东方博宜OJ一般能接受行尾空格但如果遇到严格比对的题目你需要用i 0的特判来避免最后的空格。3.2 1207统计字符串中大写字母个数这题需要遍历字符串并对每个字符判断是否属于大写字母。如果题目给的字符串不含空格直接用cin s就行如果包含空格必须用getline读取整行。#include iostream #include string using namespace std; int main() { string s; getline(cin, s); int cnt 0; for (int i 0; i s.length(); i) { if (s[i] A s[i] Z) { cnt; } } cout cnt endl; return 0; }这里用字符比较而不是ASCII码值比较读起来更清晰。如果你用的是cin s要小心输入缓冲区里残留的换行符。比如前面读了一个整数n后面用getline读字符串会先读到一个空串这种情况需要在整数读完后用cin.ignore()把换行清掉。这个坑在OJ里非常经典。3.3 1208最大公约数求两个正整数的最大公约数最经典也最保险的是辗转相除法。原理是两个数的最大公约数等于较小数和两数相除余数的最大公约数。代码很短但理解起来需要点时间。#include iostream using namespace std; int main() { int a, b; cin a b; while (b ! 0) { int r a % b; a b; b r; } cout a endl; return 0; }如果你习惯用函数也可以写成递归版int gcd(int a, int b) { return b 0 ? a : gcd(b, a % b); }但注意递归版要防止栈溢出好在这里的数不会太大。很多人在纸上画流程觉得“懂了”一写代码就把a % b换成a / b结果完全不对。记住先取余再交换和斐波那契的滚动更新是同一个套路。3.4 1209判断素数素数的定义是只能被1和自身整除的正整数1不是素数。最笨的办法是从2检查到n-1但这样效率低优化到根号n就够了。#include iostream #include cmath using namespace std; int main() { int n; cin n; if (n 2) { cout NO endl; return 0; } bool flag true; for (int i 2; i * i n; i) { if (n % i 0) { flag false; break; } } if (flag) { cout YES endl; } else { cout NO endl; } return 0; }i * i n比i sqrt(n)好在不会因为浮点数精度出问题也不用额外引入cmath。不过乘法在i很大时也可能溢出更稳妥的写法是i n / i。这题很多人的错误点是没有特判n小于2的情况比如输入1应该输出NO结果因为循环没进去直接输出YES了。边界条件永远是OJ最阴的地方。3.5 1210水仙花数水仙花数指的是一个三位数其各位数字的立方和等于它本身比如153等于1的立方加5的立方加3的立方。题目通常要求输出所有满足条件的三位数。#include iostream using namespace std; int main() { for (int n 100; n 999; n) { int a n / 100; int b n / 10 % 10; int c n % 10; if (a * a * a b * b * b c * c * c n) { cout n endl; } } return 0; }拆位数是这题的核心三个表达式分别取出百位、十位和个位。n / 10 % 10的意思是先整除10去掉个位再对10取余得到十位这个顺序不能写反。如果你只会用字符串转数字的方式去做也能做但比赛里尽量用算术方式更快更稳。4. 提交OJ时的隐藏坑格式、换行、超时我从1201刷到1210发现真正让新手反复提交的往往不是算法本身而是评测系统那些“没说出口”的规矩。下面这几个坑几乎每个人都踩过。4.1 输出格式多一个空格都WA东方博宜OJ这类在线评测系统比对输出时通常是逐字符比对。也就是说答案中多一个空格、少一个换行都会被判定为答案错误。比如打印数组时很多人习惯最后一个数后面也加空格有的题目会判错。稳妥的做法是遍历时如果i 0先输出一个空格再输出当前元素这样行尾就不会有多余空格。for (int i 0; i n; i) { if (i 0) cout ; cout a[i]; }4.2 换行与缓冲区残留输入数据可能在多行也可能在一行。cin会忽略空格和换行所以大部分整数读取不需要特别处理。但一旦涉及字符串尤其使用getline就要小心前面有没有残留换行符。我见过最典型的情况是先读n再用getline读字符串结果s是个空串。解决办法就是在中间加一行cin.ignore();。这个操作虽然不起眼但比赛中不知道卡了多少人。4.3 数据范围int溢出总是在你最没防备时出现1202累加和的溢出我说过一次但这十道题里还有斐波那契、水仙花数这类题目。拿斐波那契来说第46项左右就超过int范围了如果题目给的n比较大你还用int存那结果就是错的。建议在不确定时直接声明成long long至少少一个隐患。判断素数的循环边界也要注意i * i在i到10万时是10的10次方已经超过int所以更推荐i n / i的写法。4.4 数组开小导致越界数组下标越界在OJ上是运行时错误有时候会直接显示“Runtime Error”有时候则因为未定义行为导致随机WA。我习惯把数组长度比题目上限多开5到10个比如题目说n最大100我就开105。这不会浪费多少内存但能避免很多奇怪的问题。5. 刷完这十题后你应该继续练什么1201-1210只是起点但也是很好的起点。把这几题彻底弄懂之后接下来的路会顺很多。我觉得比多刷题更重要的是建立自己的“刷题反馈循环”。5.1 从“看答案”到“写题解”我看过太多同学把代码复制进OJAC后就关掉页面过几天回来照样不会。我自己后来改变做法每AC一道题就用自己的话把思路写下来不写代码只写“先做什么再做什么为什么这么做”。等过三天再翻出来看着笔记重写代码。这样做一次比抄十道题都有用。你现在搜到这篇答案也可以先AC然后合上代码自己重新敲一遍哪怕敲不出来也远比直接粘贴有收获。5.2 举一反三把1201-1210改编成新题这十题能扩展出很多变体。比如1204打印直角三角形改成打印等腰三角形、菱形、空心三角形1205斐波那契改成跳台阶问题1209判断素数改成统计区间内素数个数。这些变体在东方博宜OJ上都有类似题目比如很常见的“空心正方形”就是图形题的进阶版。你在搜答案时如果看到这些热词不用觉得陌生它们全是1201-1210这些基础考点的变形。5.3 补上算法常识复杂度、边界、调试刷完这十题你应该开始接触“时间复杂度”和“空间复杂度”这两个概念。1205用递归会超时1209用2到n-1枚举在大数时会很慢这些都是复杂度问题。理解复杂度之后写代码前就会多想一步这个数据范围我的算法能不能在1秒内跑完这种意识越早建立越好。最后再分享一个我调试时常用的笨办法如果提交WA不要盯着代码发呆回来看样例输出。把样例输入复制进去看自己的输出和样例是否完全一致包括空格和换行然后自己造几组边界数据比如0、1、负数、最大值。这十道题虽然基础但把边界吃透后面刷任何题都会受益。别急着跳过一个个试过来你会发现在OJ上“答案”不是一个结果而是一套不断调试的方法。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价