NOIP分区联赛
联赛命题宗旨
全国青少年信息学奥林匹克联赛(NOIP)是一项面向全国青少年的信息学竞赛和普及活动,旨在向那些在中学阶段学习的青少年普及计算机科学知识;给学校的信息技术教育课程提供动力和新的思路;给那些有才华的学生提供相互交流和学习的机会;通过竞赛和相关的活动培养和选拔优秀的计算机人才。
竞赛的目的是为了在更高层次上推动普及。本竞赛及其相关活动遵循开放性原则,任何有条件和有兴趣的学校和个人,都可以在业余时间自愿参加。本活动不和现行的学校教学相冲突,也不列入教学计划,是课外性质的因材施教活动。参加者可为初高中学生或其他中等专业学校的青少年。
普及的内容涉及
.计算机的基本组成;
.计算机工作的基本原理;
.计算机程序设计的基本方法;
.至少一门高级程序设计语言;
.程序设计中常用的数据结构。
普及的重点是根据中学生的特点,培养学生学习计算机的兴趣,使得他们对信息技术的一些本质和核心的东西有更多的了解,提高他们创造性地运用程序设计知识解决实际问题的能力。对学生的能力培养注重
.想象力与创造力;
.对问题的理解和分析能力;
.数学能力和逻辑思维能力;
.对客观问题和主观思维的口头和书面表达能力;
.人文精神。包括与人的沟通和理解能力,团队精神与合作能力,恒心和毅力,审美能力等。
竞赛形式和成绩评定
联赛分两个年龄组:初中组和高中组。每组竞赛分两轮:初试和复试。
.初试形式为笔试,侧重考察学生的计算机基础知识和编程的基本能力,并对知识面的广度进行测试。程序设计的描述语言采用Pascal或Basic。各省市初试成绩在本赛区前百分之十五的学生进入复赛,其分数不计入复赛的成绩。初赛时间为10月的最后一个星期六下午 2:30 - 4:30举行。
.复试形式为上机,侧重考察学生对问题的分析理解能力,数学抽象能力,驾驭编程语言的能力和编程技巧、想象力和创造性等。程序设计语言可采用 Pascal或C/C++等。各省市竞赛的等第奖在复试的优胜者中产生。时间为 3 小时。只进行一试,约在当年的11 月的最后一个周六进行。
试题形式
每次联赛的试题分四组:初中组初试赛题;初中组复试赛题;高中组初试赛题;高中组复试赛题。其中,初中组初试赛题和高中组初试赛题类型相同,初中组复试赛题和高中组复试赛题类型相同,但初中组和高中组的题目不完全相同,高中组难度略高;以体现年龄特点和层次要求。
.初试:初试全部为笔试,满分100分。试题由四部分组成:
1、选择题:共20题,每题1.5分,共30分。每题有5个备选方案;前10个题为单选题门每题有且只有一个正确答案),后 10题为复选题(即每题有1至5个正确答案,只有全部选对才得分)。试题内容包括计算机基本组成与原理、计算机基本操作、信息科技与人类社会发展的关系等等。
2、问题求解题:共2题,每题5分,共10分。试题给出一个叙述较为简单的问题,要求学生对问题进行分析,找到一个合适的算法,并推算出问题的解。答案以字符串方式给出,考生给出的答案与标准答案的字符串相同,则得分;否则不得分。
3、程序阅读理解题:共4题,每题8分,共32分。题目给出一段程序(没有关于程序功能的说明),有时也会给出程序的输入,要求考生通过阅读理解该段程序给出程序的输出。输出以字符串的形式给出,如果与标准答案一致,则得分;否则不得分。
4、程序完善题:共 2题,每题 14分,共 28分。题目给出一段关于程序功能的文字说明,然后给出一段程序代码,在代码中略去了若干个语句并在这些位置给出空格,要求考生根据程序的功能说明和代码的上下文,填出被略去的语句。填对的,则得分;否则不得分。
.复试:复试的题型和形式向全国信息学奥赛(NOI)靠拢,全部为上机编程题,但难度略低。复试为决出竞赛成绩的最后一个环节。题目包括 4道题,每题 100分,共计 400分。难度有易有难,既考虑普及面,又考虑选拔的梯度要求。每一道试题包括:题目、问题描述、样例说明(输入、输出及必要的说明)。测试时,测试程序为每道题提供了十组测试数据,考生程序每答对一组得10 分;累计分即为该道题的得分。
试题的知识范围
考试内容主要包括:计算机发展史、计算机组成、计算机基本原理、计算机程序设计、计算机日常应用等。要求考生掌握至少一门高级程序设计语言(详见竞赛大纲)。为了保持竞赛内容的相对连续性,试题涵盖的知识点和题型至少6O%应出现在普及类的参考书目中,其余内容可能超出该范围。
为了考核学生的基础知识、综合应用能力,激发学生的求知欲和创新思维,体现“与时俱进”的特点,竞赛题型在保持大纲相对稳定、优秀学生可能接受和理解的基础上,按照下述趋势适当变化
1、增大与课内知识结合的紧密度;
2、增大解题方法的多样性和灵活程度;
3、增大开放性试题的比例。
备战NOIP需要注意的地方
1、良好的心态。无论竞赛多么重要,都不要在考试的时候考虑考试之前或以后的事,这很重要……
2、充足的睡眠和营养。竞赛之前睡好觉,吃好饭,多吃甜食(据我们老师说在吃甜食后15分钟和2小时会各出现一次血糖高峰,会有比较好的竞技状态)。还有,宁可撒尿也不要口渴……口渴会严重影响思路……而尿素有兴奋作用,有利无害……
3、正确的时间安排。一般来说应该先想完所有的题再开始做,但有的题想不出来的时候一定要给想出来的题留出时间。
4、算法的学习。一般的DFS/BFS、贪心、各种DP、二分法、排序、lr论文中的各种奇特算法、最短路、最长路、图的DFS/BFS、最大匹配,最大最小匹配、最佳匹配、差分限制系统、最长不xx子序列、高斯消元、数论算法……
5、数据结构的学习。Hash、并查集、邻接表、边表、堆、树状数组和线段树及它们的多维形式、链表、单词查找树……
6、关于混分:超时的搜索/DP往往能比错误的贪心得到更多的分。
7、数学很重要。比如母函数……
8、专用的方法胜于通用的方法。
9、好的题目往往不能直接用经典算法解决。
10、真正难题的标程往往很短。
11、如果n很大,用汇编写的O(n^2)的程序绝对不如用QB写的O(n)的程序快。
12、如果n很小,利用压缩存储提高速度的O(n^2)的算法有可能比一般的O(n)算法快。
13、如果一个数学问题很复杂,那么看结果找规律有可能比数学推导快。
14、不要总把logn忽略掉。
15、即使是多项式算法,有时也可以加入很有效的剪枝。
16、做一道好题胜过做n道烂题,但如果不做烂题,可能会影响做好题的速度。
比赛技巧
关于调试和测试:
1.下面是几种比较常见的错误:
1.输入输出格式错误
2.数据类型错误(尽量用大的类型)
3.范围检查错误(可以稍稍加大上下界)
4.变量名称错误
5.漏语句(看事先设计好的变量是否都用上了,然后看每个模块是否实现了应有的功能,是否完成了接口)
2.我们应对于每道题设计充分的测试数据,并保留那些比较具有代表性的测试数据,以便于优化的时候比对.
3.一定要记住删除屏幕输出!
4.最后一定要记住关闭程序中用于临时调试的特殊设置和语句!
5.输出数据的每一行(包括最后一行)必须以一个换行符结束,行末不要保留多余空格。对于每一道试题,在相应的目录中都有一个格式检查程序来检查输出文件格式的合法性。该程序的文件名是:<shortname>_check。格式检查程序仅仅检查输出文件名的正确性和文件格式的合法性而不检查结果的正确性。检查结果显示在屏幕上。
6.如果领队或参赛选手对评测结果有异议,可以填写相应的表格,并在评测结果公布后的三个小时之内提交评测委员会申请复议或复评。当领队或参赛选手对复议或复评结果仍有异议时,应提交NOI科学委员会仲裁,并以NOI科学委员会的仲裁结果为该项评测的最终结果。
7.调试的时候,一定要钻输入文件的牛角尖,考虑到各种情况。
8.调试的时候,常常可以编一个非常非常易编的程序,采用算两次的方法,不过前提是必须保证正确。
9.Writeln是Fp中最笨但又是最准确的调试方法。
10.调试时每发现一个错误,都最好浏览一下整个程序,看是否有类似错误,这样非常有效!
11.在每一处可以中止程序的地方,都要看一看是否需要close file.
12.程序出现不确定性的问题,如对于同样数据,有时死机,有时不死机,但多半都是随机模块有误!
13.指针出错常常是出现了Nil^.Next
14.递归程序的调试应该使用F7(F8)+Call Stack,尽量不要用F4。
15.不要只顾埋头拉车,要抬头看路。当被一两个子程莫名其妙的错误弄得晕头转向的时候,记住:很可能错误在其他地方。
16.读写文件之前才打开文件,操作完毕立即关闭。
17.每改完一个错误要想想是否改正确了,是否改彻底了,程序中(特别是有Paste的地方)是否有相同错误。
18.很多题目最易忽视的就是初状态=末状态的情况,还有初状态和末状态存在可操作的决策。(如Mars Explorer)
19.多考虑一些特例,在这方面认真些,全面些,仔细些,常比多考虑些时空上限划算得多。
20.编函数的时候千万别忘了给函数赋返回值,否则会引起随机性错误。
21.调试语句一般和上下文保留一空行,最好加上注释,并且一定记住在最后删除。
22.中途输出后结束一定要记住Halt
23.Byte,Shortint调试会以String类型出现,第一位以字符串长处理,遇到#0中止。FP和RHIDE中皆如此。
24.FP中的Extended类型有时候变量值未改变。
25.调试和测试的时候一定要充分考虑到各种边界和特殊情况。
26.自测时千万不要忘测数据上限,主要是看是否会超界。大半错误均源于此!之后仔细察看Const中的数。
27.大数组处理很容易出错,所以尽量避免开过大的数组及其调试。
28.多维数组的调试RHIDE比FP Bug还多,而大数组多元素的查看可考虑使用RHIDE
关于算法
1.关于复杂度涉及logN的算法.logN常常是因为二分,树,Heap,排序等造成的,而且有一点应该注意到,logN更接近一个常数,而不是N.
2.涉及矩阵的统计问题,通常而言,降维策略是非常有效的,而且常常是在外层枚举用土方法,内层枚举使用优化过的方法。另外,用O(N*N)枚举出Y1,Y2,然后考察之间夹的矩形是非常常用的方法。
3.涉及01串的问题,都不要忘记位运算和压缩,同时也要小心。
4.对于判重问题,关注最小表示。
5.有序化的处理常常比无序的简单,所以,对于想不出算法的题目,先有序化!
6.对于涉及子序列之和的问题,如NOI Sequence ,CEOI Parity,B&W,常常化为第一位到某一位的和。
7.大数据量的题目,有时候分多次读入数据会非常有效
8.对于一边明显长于另外一边的矩形问题,常常是基于短边的指数化或者是阶乘算法,而基于长边的O(N)或者O(N*N)的算法。
9.我们应该注意,许多求割点的题目是求给定两点间的割点,而不是普遍意义上的割点。
10.没有回溯的搜索是最成功的搜索。
11.如果你的算法在最大规模的时候要爆,但是最大规模的数据非常难设计,那么就不要管他,设计一个稍次一点的算法就行了。
12.尽量让程序不做已做过的事和显然没有必要的事,也不要解决无用的子问题和对结果进行无意义的引用。
13.A*算法的估价函数一般而言要保守些,不要为了速度的一点提升丢失了最优解。
14.一般情况下,根据数据规模猜算法是非常有效的。
15.聚焦边界!
16.对于流量不超过给定值的最大流问题,注意取流值的时候。
17.Qsort算法要注意应该先存储选为基点的那个数以后再比较,比较函数一定要保证Compare(A,A)=False!
18.我们不仅关心算法的时间复杂度,还要关注最内层的循环到底在干什么。
19.在只涉及乘除的高精度运算中,按因数存储的效率远高于按位存储的效率。
20.动态规划和递推更多应考虑本问题由哪些已解决子问题构成,而不是考虑本问题对将来哪些问题有贡献。
21.深度优先搜索候(如求割顶、桥、强连通分支),一定要记住常常题中不止一棵搜索树,也常常有重边!
22.优化的时候不要去考虑最坏的情况下是否有太大的意义,只要在大多数情况下有比较明显的作用就行。
23.对于大规模的Dijkstra算法,如果数据不容易出得很刁的话,用迭代代替堆也是不错的选择。用可更新队列实现也不错。
24.很多图论模型中都要考虑到重边,即使是自己建的图中也有可能出现重边(Knights)。
25.很多情况下,“不超前”属性的引入可以使复杂度降低一个数量级。
26.很多时候,由于DP空间开销很大,我们只能保留一个阶段,这时候从大到小的规划时常收效颇佳。
27.对于数学味较浓的问题,变量的取值范围与计算公式同等重要。
28.博弈问题从残局或结局出发分析往往会有惊人的发现。
29.博弈问题胜负局面的相加运算符合Xor(也就是和mod 2)
关于数据结构
1.涉及单词的问题,常常因为单词的数目多,而且长短不一,出现存储问题,我们可以读入整个数据文件,然后对每个单词记录起止点,这样就充分利用了空间。
2.事实上,链表的速度并不比有序数组高多少,虽然具有O(1)的插入删除复杂度,但是他的查找是O(N)的,而有序数组虽然插入删除是O(N)的,但是查找是O(logN)的。而且后者好编些。
3.多用Longint,少用Integer,反正闲着也是闲着。
4.传统数据结构的创新性珠联璧合是现代数据结构试题的发展方向。比如邻接矩阵+邻接链表。
5.Joseph类问题中,如果采用静态数组,删除节点可能导致指针错误。
6.并查集Combine时切记看两个Fa是否相同,否则可能引入圈。
7.Bignum有时应注意[0]不止256位
8.有时候,将链表和数组珠联璧合,如在大规模约瑟夫环中,会受到很好的效果。
9.在处理小规模链表的问题中,采用静态指针(数组)效果比较理想,便于调试。(比如多维背包)
todo
关于FP及程序实现
1.有时候要有意采用ln,exp变*为+
2.有时与其追求非常精炼代码,还不如笨拙的枚举各种情况,只是注意在Copy&Paste的时候不要出错。
3.涉及坐标的问题,常常要考虑坐标的定义是基于最小区间的还是基于点的。
4.Linux中虽然FP IDE中Ctrl失效,但执行程序的时候,Ctrl+Pause或者Ctrl+Z(C)是可以用的
5.对于涉及时间的问题,我们必须注意题目中所说的时间是指时间段还是指时间点。
6.凡是分母为变量的除法、Div、Mod都需要想一想是否要判0
7.永远不要忘记在程序调试完以后改大Const!
8.双向搜索与其在精炼的代码上挣扎,还不如就两边分别写过程,只是注意不要乱Copy&Paste.
9.链表的实现常常可以采用虚节点的方法,但不要生搬硬套,有时候采用虚节点不一定更好.
10.非等差循环用while不用for.
11.实数运算永远记住用Zero!(要除了计算几何的一些经典算法,如Graham)。
12.Gcd,路经压缩,二分查找等很短的递归最好化为非递归形式
13.记住,测试数据只是用来发现错误,而不是用来改正错误的,依靠测试数据改正错误,越改越糊涂!
14.注意计算几何中Infinite的引入。
15.很多时候,输入的两个数据并没有说明两者的大小关系!
16.注意FillWord和FillDWord分别是Div2,Div4,而后者类型为Dword,可正可负。
17.枚举的时候不要忘记想一想是用To还是Downto更好。
18.编写DFS之前一定要先考虑最坏的情况下栈空间是否够用。
19.Int64不能用Read,也不能直接赋给一个大于Longint的值。
20.Gcd中,我们不用if a mod b=0 then gcd:=b else gcd:=gcd(b,a mod b),而用if b=0 then gcd:=a else gcd:=(b,a mod b),因为前者用了两个Mod.
21.Gcd,Mod,Div的使用都应该注意正负。
22.交互问题一定要注意接口。
23.开大数组相当花时间。
24.A mod 8=A and 7
25.编之前应该想好需要变的子程,不要做无用功,同时也为反复调用提供思路。
26.重要结论:a,b取值为{0,1},则a xor b=(a+b) mod 2
27.FP中不要使用集合
28.对于取余输出,我们用(a-b+c) mod c而不是(a-b) mod c
29.一定不要忘记初始化。
30.在很多情况下,Xor运算可以使代码更简洁高效。
其它
1.在竞赛开始的一个小时之内,参赛选手可以就试题中模糊不清的内容提出疑问。提问应使用专用表格,一题一表。回答内容应是“是”、“否”、或“无可奉告”。等待答案的时间计算在选手竞赛时间之内。
2.在竞赛期间,参赛选手应及时将自己的文件备份,以便当出现设备故障时迅速恢复文件。文件备份应放在/tmp目录之下。
3.理解题意的时候千万不要想当然,只去做题目说的东西,不要假设任何题目没有提及到的条件。
4.表达式处理中注意形如(a+b)*(c+d)的括号。
5.有少数题目不是按照先行后列的方式组织数据的,这一点要格外注意。
6.记住:非明文禁止者,皆不无可能。
7.比赛不要轻易删文件,尤其不要加通配符。
8.文件名切记要使用小写!
9.Settextbuf在Linux下面同样有用。
10.要小心,10^8有9位,不是8位。9E14是指9*10^14,不是 9^14 !
11.当对程序有利时浪费内存。
12.保留所有版本的程序。
13.使用预处理。
14.注意对称性。
Pascal常见运行错误
002 文件未找到
005 文件拒绝访问
102-105 (检查assign,reset,rewrite)
106 无效数字类型
200 除以0
201 范围检查错误
202 栈溢出
203 堆溢出
204 无效指针运算
205 浮点溢出
206 浮点下溢
207 无效浮点操作
216 常规保护错误