[18考研]复试中“机试”是什么?应该如何准备?

本文转载了一部分王道机试指南中的内容

提醒:这篇文章是新手向,适合 跨专业/没接触过ACM/不懂机试 的同学,ACM大神可以直接关掉不看了。

什么是机试

众所周知,机试是计算机考研当中非常重要的一个环节。在越来越注重实践动手能力的今天,越来越多的知名高校在计算机研究生招生考试当中采用了机试的形式,通过这种考试手段来考察考生分析问题并利用计算机程序解决问题的能力。通过机试,可以考察一个考生从实际问题当中抽象得出数学模型的能力,利用所学的计算机专业知识对该模型进行分析求解的能力,以及利用计算机编程语言,结合数据结构和算法真正解决该实际问题的能力。

所以,我们在准备机试的过程中要特别注意以下几个方面:

1、如何将一个实际问题抽象成数学问题。例如将高速公路网抽象成带权图,这就是一种简单的、直接的抽象。

2、如何将我们所学的计算机专业知识运用到解决抽象出来的数学模型上去。这就要求我们在脑子里事先熟知一些常用的数据结构和算法,再结合模型求解的要求,很快地选择合适的编程思想来完成算法的设计。甚至可以利用一些经典算法特征,加入一些自己的优化,使得编写的程序更优雅、更高效(当然这是建立在充分理解经典算法的基础上)。

3、如何将我们为解决该数学模型所设计的算法编写成一个能被计算机真正执行的计算机程序。我们认为,关于这个能力的定义有三个层次:1)会编写(默写)一些经典算法的程序代码。2)能够将自己的想法或设计的算法转换为程序代码。3)能够使得自己编写的程序在大量的、多种多样的、极限的测试数据面前依旧正常完成功能(程序的健壮性)。我们在准备机试的训练过程中,就要依次经历这三个层次,从而最后能够在实际考试当中取得理想的成绩。

机试的形式

而 ACM 是目前所有高校机试所采取的唯一形式,因此提早开始准备和练习,对于一个完全没有接触过 ACM 的计算机考研人来说,是必须的!

 

绝大部分机试所采用的形式,归结起来可以概括为:得到题目后,在计算机上完成作答,由计算机评判并实时告知结果的考试过程。

机试考试中的问题往往有五部分组成。

首先是问题描述,问题描述描述该问题的题面,题面或直接告知考生所要解决的数学问题或给出一个生活中的实际案例,以待考生自己从中抽象出所要解决的数学模型。

第二是输入格式,约定计算机将要给出的输入数据是以怎样的顺序和格式向程序输入的,更重要的是它将给出输入数据中各个数据的数据范围,我们通过这些给出的数据范围确定数据的规模,为我们设计算法提供重要依据。

第三是输出格式,明确考生将要编写的程序将以怎样的顺序和格式向输出输出题面所要求的答案。

第四第五部分即输入、输出数据举例(Sample)。好的 Sample 不仅能为考生提供一组简单的测试用例,同时也能明确题意,为题面描述不清或有歧义的地方做适当的补充。

另外我们也要特别注意,题目中给定的两个重要参数:1、时间限制。2、空间限制。这两个重要的参数限定了考生提交的程序在输出答案之前所能耗费的时间和空间。

我们来看一个典型的题目描述,从而了解机试题的问题形式。

题目选自HDOJ 1231

最大连续子序列

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 35982    Accepted Submission(s): 16246

Problem Description

给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },其中 1 <= i <= j <= K。最大连续子序列是所有连续子序列中元素和最大的一个, 例如给定序列{ -2, 11, -4, 13, -5, -2 },其最大连续子序列为{ 11, -4, 13 },最大和为20。 
在今年的数据结构考卷中,要求编写程序得到最大和,现在增加一个要求,即还需要输出该子序列的第一个和最后一个元素。

 

Input

测试输入包含若干测试用例,每个测试用例占2行,第1行给出正整数K( < 10000 ),第2行给出K个整数,中间用空格分隔。当K为0时,输入结束,该用例不被处理。

 

Output

对每个测试用例,在1行里输出最大和、最大连续子序列的第一个和最后一个元 
素,中间用空格分隔。如果最大连续子序列不唯一,则输出序号i和j最小的那个(如输入样例的第2、3组)。若所有K个元素都是负数,则定义其最大和为0,输出整个序列的首尾元素。 

 

Sample Input

6
-2 11 -4 13 -5 -2
10
-10 1 2 3 4 -5 -23 3 7 -21
6
5 -8 3 2 5 0
1
10
3
-1 -5 -2
3
-1 0 -2
0

Sample Output

20 11 13
10 1 4
10 3 5
10 10 10
0 -1 -2
0 0 0

得到题目后,考生在计算机上立即编写程序。先在本地编译测试,确认无误后,将该程序源代码提交给评判系统。评判系统将考生提交的源代码编译后,将后台预先存储的输入测试数据输入考生程序,并将该程序输出的数据与预先存储在评判系统上的“答案”进行比对得出结果。

评判系统评判考生程序后,实时地将评判结果返回考生界面,考生可以根据该结果了解自己的程序是否被评判系统判为正确,从而根据不同的结果继续完成考试。

评判结果

本节将对评判系统评判考生提交程序后返回的结果做详细的说明,并且针对不同的返回结果,对可能出现错误的地方作出初步的界定。

Accepted(答案正确):你的程序对所有的测试数据都输出了正确的答案,你已经得到了该题的所有分数,恭喜。

Wrong Answer(答案错误):评判系统测试到你的程序对若干组(或者全部)测试数据没有输出正确的结果。

出现该种错误后,一般有两种解决方向:如果对设计的算法正确性有较大的把握,那么你可以重点考虑代码健壮性,即是否存在某些特殊数据使程序出现错误,比如边界数据,比如程序中变量出现溢出。另一种方向,即怀疑算法本身的正确性,那么你就需要重新考虑你的算法设计了。

Presentation Error (格式错误):评判系统认为你的程序输出“好像”是正确的,只是没有严格按照题目当中输出所要求的输出格式来输出你的答案,例如你忽略了题目要求在每组输出后再输出一个空行。

出现这种错误,往往预示着你离完全正确已经不远了,出现错误似乎只是因为多输出了一些空格、换行之类的多余字符而已。但这不是绝对的,假如在排版题(后文会有介绍)中出现格式错误,那么有可能你离正确的答案仍然有一定的距离。

Time Limit Exceeded (超出时间限制):你的程序在输出所有需要输出的答案之前已经超过了题目中所规定的时间。

若这种结果出现在你的评判结果里,依然有两种方向可供参考:

1、假如你确定算法时间复杂度能够符合题目的要求,那么依旧可以检查是否程序可能在某种情况下出现死循环,是否有边界数据可能会让你的代码不按照预想的工作,从而使程序不能正常的结束。

2、你设计的算法时间复杂度是否已经高于题目对复杂度的要求,如果是这样,那么你需要重新设计更加高效的算法或者对你现行的算法进行一定的优化。

Runtime Error (运行时错误):你的程序在计算答案的过程中由于出现了某种致命的原因异常终止。

你可以考虑以下几个要点来排除该错误:

1、程序是否访问了不该访问的内存地址,比如访问数组下标越界。

2、程序是否出现了除以整数 0,从而使程序异常。

3、程序是否调用了评判系统禁止调用的函数。

4、程序是否会出现因为递归过深或其他原因造成的栈溢出。

Compile Error (编译错误):你提交的程序并没有通过评判系统的编译,可根据更详细的编译信息修改你的程序。

Memory Limit Exceeded (使用内存超出限制):你提交的程序在运行输出所有的答案之前所调用的内存已经超过了题目中所限定的内存限制。

造成这种错误的原因主要有两个方面:

1、你的程序申请过多的内存来完成所要求的工作,即算法空间复杂度过高。

2、因为程序本身的某种错误使得程序不断的申请内存,例如因为某种原因出现了死循环,使得队列中不断的被放入元素。当然也千万别忽略自己的低级错误,比如在声明数组大小时多打了一个 0。

Output Limit Exceeded (输出超出限制):你的程序输出了过多的东西,甚至超出了评判系统为了自我保护而设定的被评判程序输出大小的最高上限。

一般来说该种错误并不常见,一旦出现了也很好找原因。要么就是你在提交时忘记关闭你在调试时输出的调试信息(我经常输出 DP 时的数组来动态的观察状态的转移);要么就是程序的输出部分出现了死循环,使得程序不断地输出而超出系统的限制。

以上几种结果就是评判系统可能会返回的几个最基本的结果。若返回Accepted,则你可以获得该题的所有分数。若返回其它错误,则根据不同的考试规则,你的得分将会有一定的差异。若你参加的考试采用按测试点给分规则,你依然能够获得你通过的测试点(即该程序返回正确结果的那部分测试数据)所对应的分数;但是,若你参加考试采用所有数据通过才能得分的评分规则,那么很可惜,到目前为止你在这道题上的得分依旧是 0 分。

假如评判结果显示你提交的程序错误的,你可以在修改程序后再次提交该题,直到获得满意的分数或者放弃作答该题。

OJ系统

我们该去何处开始我们的机试训练和模拟考试呢?可能大部分人已经听说过在线评判系统(Online Judge),例如题目来源的HDOJ。

在这里列一下部分OJ系统的网址:

北京大学POJ

http://poj.org/

杭州电子科技大学HDOJ

http://acm.hdu.edu.cn/

王道的九度OJ

http://ac.jobdu.com/(貌似现在关了?)

LeetCode

https://leetcode.com/

浙大PAT

https://www.patest.cn/

等等。。。。

但是这些OJ一般都是为ACM/ICPC训练而设计的,虽然形式与机试大同小异,但是难度却有较大差别。

所以我们建议同学们选择一些适合自己的OJ系统。

如果报考的学校有自己的OJ系统的话,建议选择它进行练习,说不定考试时会有类似风格的题目出现。

关于学习

同学们在OJ上进行练习的时候,如果遇到实在做不出来的题目,可以去网上寻找一下相关的题解,看看网友们的正确答案是什么样子。题解可以在搜索引擎中输入OJ名称+题号即可查到。也可以在像GitHub等平台中搜索。

对于一些新手,可能看别人的题解也看不懂。这就需要你搜索出解那道题需要哪些算法,然后对应的去学习。

当然 也可以看一些书籍来学习。

这里推荐几本:

王道考研系列·计算机考研:机试指南

(就是转载的这本)

算法笔记上机训练实战指南-算法考试和考研机试

(PAT题解)

算法竞赛入门经典  刘汝佳

(ACM的经典书籍)

同学们有什么好的书籍推荐,也可以在下面留言。

最后,感谢王道机试指南~

你可能感兴趣的:([18考研]复试中“机试”是什么?应该如何准备?)