《ACM程序设计》课程总结

目录

 

一、我校ACM程序设计竞赛的现状

二、我对这门课的理解

三、我为什么要选择这门课

四、对这门课的体会

五、我从这门课中学到了什么

六、这门课对我的发展方向有什么帮助 



正文


一、我校ACM程序设计竞赛的现状

  ACM国际大学生程序设计竞赛(英文全称:ACM International Collegiate Programming Contest(简称ACM-ICPCICPC))是由美国计算机协会ACM)主办的,一项旨在展示大学生创新能力、团队精神和在压力下编写程序、分析和解决问题能力的年度竞赛。经过近40年的发展,ACM国际大学生程序设计竞赛已经发展成为全球最具影响力的大学生程序设计竞赛。赛事目前由IBM公司赞助。

 

  ACM国家大学生竞赛自1996年起设立中国大陆地区预选赛赛区,并由上海大学承办,至2001年总决赛止,连续举办五届。之后在境内设置多个赛点,由各大学轮流主办区域选拔赛至今。

ACM-ICPC以团队的形式代表各学校参赛,每队由至多3名队员组成。每位队员必须是在校学生,有一定的年龄限制,并且每年最多可以参加2站区域选拔赛。

 

  近年来,我国各大高校逐渐开始重视ACM程序设计竞赛,每年的Final总决赛上都会出现我国选手的影子。以上海交通大学、清华大学、北京大学、浙江大学、复旦大学为代表的我国高校屡次在总决赛中捧杯,为我国争取了荣誉,也在世界上确立我我国的地位。

我校作为山东省重点省属高校之一,ACM水平在省内维持着前五的水平,虽为农业大学,但是在这种理工科的竞赛中也拥有绝对的话语权和地位。

但是在我看来,我校的算法竞赛的氛围还不算浓厚,这与我校是农业类大学的学校定位以及我院的领导阶层也没有给予一定的重视有一定关系,诸位教职工中也鲜有人能够足够重视。同时,相关的校内赛匮乏,甚至有些计算机系的同学都不知道什么是ACM/ICPC,所以我认为这种情况亟待改善,院方应引起足够的重视,并且经常性的举办比赛,并设置奖品,来引起同学们的注意。

 

二、我对这门课的理解

ACM程序设计竞赛,着重的考察的是参赛者的算法能力,众所周知,算法是一个程序的灵魂和地基,一切的软件、程序和工程都建立在一定的算法和数据结构之上,学习这门课,就是在学习算法,学习解决问题的方法,并在实际的刷题之中提高解决问题的能力和对问题的应变能力,从而达到锻炼自己的目的。

 

三、我为什么要选择这门课

一个优秀的程序员就像是一位 “武林高手”一样,需要掌握 “内功”和“外功”,外功指的就是程序设计语言,比如C、C++、Java、Python。而内功就是指算法,数据结构,设计模式等等。 这“内功”和“外功”缺一不可。

有一些程序员,只顾着去学习“外功”,而不去修炼“内功”,其结果就是虽然掌握了许多时髦的程序设计语言,但是却写不出好的程序,亦或是只会简单的重复别人写的包和库,而不会自己去创造,从而成为我们所说的“码农”。

为了成为一个优秀的软件工程师,而不是一个普通的 “码农”,我选择了这门课,为的就是锻炼自己的算法能力以及思考能力,探索解决问题的方法,了解一个程序运行的本质和内在机理以及支撑它的框架,从而真正的把程序握在自己的手中。

 

四、对这门课的体会

(一)ACM本身并不直接与学术界或工程界挂钩,实际上是一个既定规则下的智力游戏,通过它你可以检验自己的学习能力。

(二)上了这门课,学到的最重要的东西不是算法,而是思维,掌握了这种思维,不仅是在计算机领域,在任何领域应用它都会有所作为。

(三)因为课程提前涉及到了一部分离散数学和数据结构的知识,所以说以后学这两门课的时候会相对轻松一些。

(四)ACM竞赛就是在最短的时间内写出能AC的代码,但是正是这种刺激,导致一些恶劣的代码风格和极不规范的变量命名规则充斥其中,广受人“吐槽”。

(五)而很多搞其他事情的计算机专业的大学生,对很多东西一知半解的时候,就觉得自己牛逼到无敌。还天天跟别人吹牛逼。因为学生一般知识面没有那么宽,有些人搞出来个没人知道的奇怪东西,然后再渲染一下他搞这个东西的辛苦,很多人就会觉得他们很厉害,然后他们就会自我膨胀。但是ACM的话,很简单,打场比赛看看,你的实力基本就可以反应了。根本不用听你吹牛逼。

 

五、我从这门课中学到了什么

1.贪心算法

  贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。值得注意的是,贪心算法并不是完全不可以使用,贪心策略一旦经过证明成立后,它就是一种高效的算法。

贪心算法还是很常见的算法之一,这是由于它简单易行,构造贪心策略不是很困难。

 

从我的理解来看,目前遇到的贪心问题分为两种:背包问题,区间问题。

 背包问题属于比较简单的那种类型,上课老师讲的例题就是这种类型,这类问题要么以物品数量为标准,要么以性价比为标准,通过一次For循环即可求解。用贪心法求解背包问题的关键是如何选定贪心策略,使得按照一定的顺序选择每个物品,并尽可能的装入背包,知道背包装满。至少有三种看似合适的贪心策略。

(一)选择价值最大的物品,因为这可以尽可能快的增加背包的总价值,但是,虽然每一步选择获得了背包价值的极大增长,但背包容量却可能消耗的太快,使得装入背包的物品个数减少,从而不能保证目标函数达到最大。

(二)选择重量最轻的物品,因为这可以装入尽可能多的物品,从而增加背包的总价值。但是,虽然每一步选择使背包的容量消耗的慢了,但背包的价值却没能保证迅速的增长,从而不能保证目标函数达到最大。

(三)以上两种贪心策略或者只考虑背包价值的增长,或者只考虑背包容量的消耗,而为了求得背包问题的最优解,需要在背包价值增长和背包容量消耗二者之间寻找平衡。正确的贪心策略是选择单位重量价值最大的物品。

 

区间问题是一个难点,ProblemA等题是这类问题的代表,区间问题的特点是较难找出一个求最优解的标准,标准找不出,问题就很难解决,以ProblemA为例,解题的关键是理解串行和并行,并将通过次数最多的路段的总时间作为最优解。

除此之外,我还接触到了Huffman编码问题,哈夫曼编码是一种很著名的文本压缩方式,是一类比较特殊的贪心问题,Huffman编码从通俗上讲,就是利将固定二进制位的字符编码,变成有弹性位数的编码,出现频率越高的字符二进制的位数越短,反之则越高,通过这种方式来压缩文本,在题目中,这种问题的解决方式是利用优先队列容器,优先的标准是频率,然后将字符频率排序并入队,每次取出两个,将频率相加再次入队,直到队列为空为止。

2.搜索

广义的搜索算法分为四个大类,二分查找算法(Binary-Search),三分搜索算法(Ternary search),深度优先搜索算法(DFS),广度优先搜索算法(BFS)。前两个是针对给定公式的求解思路,后两个是针对给定图形的求解思路

 

(一)二分查找算法

  二分查找主要针对的是单调函数给定函数值,求自变量值的情况,非常简单,优点是比较次数少,查找速度快,平均性能好,二分查找的基本思想是将n个元素分成大致相等的两部分,取a[n/2]与x做比较,如果x=a[n/2],则找到x,算法中止;如果xa[n/2],则只要在数组a的右半部搜索x.。这里需要注意的是,不一定非单调函数就不能用二分,有时结合求导。可以求出函数单调性,从而求极值。例如1002题,需要先对给定函数求导,然后再二分,从而求解。

 

(二)三分搜索算法:

  分查找主要针对的是凸性函数给定函数值,  求自变量值的情况,难道较大,是在二分的基础上,对某一区间再次二分的一种算法。已知左右端点L、R,要求找到白点的位置。

思路:通过不断缩小 [L,R] 的范围,无限逼近白点。

做法:先取 [L,R] 的中点 mid,再取 [mid,R] 的中点 mmid,通过比较 f(mid) 与 f(mmid) 的大小来缩小范围。当最后 L=R-1 时,再比较下这两个点的值,我们就找到了解。

 

(三)DFS

深度优先算法属于图算法的一种,其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次.

深度优先遍历图的方法是,从图中某顶点v出发:

(1)访问顶点v;

(2)依次从v的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v有路径相通的顶点都被访问;

(3)若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。

原来对DFS的理解仅仅局限于图,现在发现这只是最基础的。DFS更多的表示的是一种状态,然后利用某中很简单的思维进行一次次的尝试,每次尝试成功了,就深入一层递归进行下一次尝试,直到之后的尝试表明已经失败了不会成功,则回溯到这里。取消这次的尝试,去尝试其他的操作。简单地说,就是暴搜。只不过利用了递归来实现尝试失败时的回溯,从而进行新的尝试。

 

(四)BFS

从算法的观点,所有因为展开节点而得到的子节点都会被加进一个先进先出的队列中,每次取出队首元素进行检验,如果符合条件,就停止,如果不符合就剔除掉,循环检验,知道队列为空位置。BFS在求解最短路径或者最短步数上有很多的应用。应用最多的是在走迷宫上,例如本专题的国际象棋问题,就是使用了此种思路。

 

3.动态规划

  动态规划程序设计是对解最优化问题的一种途径、一种方法,而不是一种特殊算法。不像搜索或数值计算那样,具有一个标准的数学表达式和明确清晰的解题方法。动态规划程序设计往往是针对一种最优化问题,由于各种问题的性质不同,确定最优解的条件也互不相同,因而动态规划的设计方法对不同的问题,有各具特色的解题方法,而不存在一种万能的动态规划算法,可以解决各类最优化问题。

动态规划问题运算量比较大,通常提前列出问题的所有可能并保存到表中,在根据键值查表,这种方法的特点是牺牲空间来换取时间,举个简单的例子,斐波拉契数列,求f(10),需要11次运算,求f(11),需要12次运算,如果用公式f(n) = f(n-1) + f(n-2)分开求,需要计算11+12=23次,但如果将将f(10)保存,计算f(11),只需在f(10)的基础上再运算一次,即11+1=12次。可见,这种做法非常节省时间。

动态规划问题,相较于贪心和搜索来说,一个显著的特点就是代码量很少,一个贪心或者搜索问题,一般都会有五六十行代码,而一个DP问题的代码量,往往就十几行甚至更短,以至于真正的核心就那么一行递推公式。但这并不代表DP问题就简单,做DP问题需要很强的逻辑思维和思考能力(思路很重要,思路好的时候,一天可以AC 5道题,要是思路不好,一天可能一道题也做不出来),需要一颗具备把逻辑问题转化为特征方程能力的大脑,总之,做DP问题,是真正用“脑子”做题,不是像搜索一样,靠“模板”来嵌套。

4.图论

图论〔Graph Theory〕是数学的一个分支。它以图为研究对象。图论中的图是由若干给定的点及连接两点的线所构成的图形,这种图形通常用来描述某些事物之间的某种特定关系,用点代表事物,用连接两点的线表示相应两个事物间具有这种关系。

在这一专题,我学到了有向图,无向图,完全图等概念,也学习了并查集,最小生成树,单源最短路径等问题的解决思路,学会了Prim,kruskal,Dijkstra等算法,也适当的了解了一些其他的算法

图论,是ACM程序设计这门课的最后一个专题,我觉得也是最难的一个专题,上述所提及的算法,只是图论中算法的极小一部分,图论的综合性比较强,比如有的图论题甚至会用到贪心或搜索的思想,所以遇到具体的问题应该具体的对待。

图论题的另一个特点是模板性非常强,对于常用的算法,只要将其编写成函数,遇到同类问题,只要将现成的函数复制进去,并且修改一下mian()函数和输入输出格式,就可以正确的得出结论。

我觉得,图论的知识在以后的工作中应用性比较强,例如在道路修建,铁路调度,电子地图制作,打车软件等领域,图论的部分思想渗透其中,所以说,学好图论很重要!

 

六、这门课对我的发展方向有什么帮助

  我个人感兴趣的发展方向是数据挖掘和大数据分析,就以数据挖掘的一个分支——网络爬虫为例,传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL放入队列,直到满足系统的一定停止条件。而这个抽取的过程就是一个搜索的过程,这就用到了深度优先搜索和广度优先搜索,而对这些信息进行汇总和整理,就会利用到一些并查集的知识,而这些算法我已经在该课程中学过了,所以在实际运用的过程中,就省下了很多力气,所以说学习这一门课,能对我在平时的编程中遇到的一些算法给出合理的解释,对我自身专业的发展方向很有帮助。



                                                                                                                                                                                                                                                                           

你可能感兴趣的:(杂项)