ACM结课总结

ACM选课收获感悟

   一、关于选课

 一个学期的ACM课程结束,首先自然是要感谢老师的,感谢老师的辛苦教学。但是这只是课程的结束,并不是说再见的时候,我还想继续在ACM这条路上走下去。

   当初选课时,受到了来自各方面的反对。因为难就不应该学吗?一座山,不会因为你不爬就降低它的高度。困难就算你无视它,它也依然在那,并不是假装看不见它就真的不存在了。与其装聋作哑,假装看不见它,不如走近了看清它,克服它。记得刚上课时,老师曾说过:“你因为难而不选这门课,不学这门课,可全国那么多学校,大部分学校都开了这门课。有那么多人都在学,你听不懂你不学,有那么多人都在学都听得懂。”差距就在这里拉开,甘心吗?不甘心。

 在众人的反对下依然坚定地选了这门课,因为我想变得更好。我觉得计算机专业就应该把时间用在提升自己的专业能力上,而学ACM是一个很好的途径。其实说实话,我对计算机专业并没有很浓厚的兴趣,我的C++基础也不是很强。但是兴趣是可以培养的,能力提高的。我就想通过选这门课来逼自己一下,让自己看得到更高的目标,让自己有动力前行。总不能借口寻找自己的兴趣而整天无所事事,兴趣是做出来的不是找出来的,不尝试一下怎么知道自己兴趣所在。

当时选课时想着逼自己一下,既然这门课难,那就花更多的时间在上面呗,哪有努力解决不了的事。要是真用心了,这门课也一定能过。当时吧,虽然是这么想的,但是实际上这门课的实际难度还是超过了我的想象。当初劝我不要选课的人这点倒是说对了,真的很难,但我也不后悔。意识到差距是缩小差距的第一步,虽然这个差距比想象中的大了好多好多。

二、选课收获

学习的第一个专题是STL,应用合理这个模板会使很多问题简化,老实说这个专题难度比较低,对我还是比较友好的。STL中的先进后出的栈和先进先出的队列,在一些题中很实用。栈只有一个出口,只能操作最顶端元素。队列可在两端操作,从队顶取出元素,从队底加入元素。动态数组可以根据实际需要开辟空间,减少不必要的内存开销。sort排序的应用可以简化步骤,可根据实际情况对cmp函数进行更改,按照需要排序,应用的比较多的是结构体数组的排序。生成排列可直接将区间内元素改变序列,递推递归专题也可以实现,不过要麻烦得多。upper_bound和lower_bound就不太常见了,只是知道有那么回事,至今还没有应用过它。set和multiset按照特定的排序准则,自动将元素排序,可以通过运算符重载按照自己的方式排序。可以利用set中的find函数查找元素,这个当时纠结迭代器是什么,平时也比较少用,现在看看才有点理解了。map和multimap映照容器,将两个元素联系起来,一个为实值,一个为键值。优先队列自动按照权值排列,权值高的排在前面。STL分为函数和容器,容器中又包含各种函数操作。

  学习的第二个专题是递推递归,递推主要找递推公式,在已知条件和所求问题之间总存在着某种相互联系的关系。首要问题是得到相邻的数据项间的关系,把一个复杂的问题求解,分解成连续的若干步简单运算。查找当前状态与上一状态的关系。递归也是查找规律。递推递归大多和数学问题相结合,有的题很简单,递推递归公式很容易写出,但有的题就很复杂。做不出来也许和数学思维的缺乏有关。递推递归思想后面的专题动态规划和搜索都有涉及。记得做递推递归专题时有个青蛙过河的问题,什么荷叶和石头,当时是完全没想到,看了题解后才会做的。上学期C++课本上感觉最难的题就是汉诺塔问题了,结果在递推递归专题这,汉诺塔找找规律后成了最简单的题。

学习的第三个专题是动态规划,这个就很不友好了,非常不友好。简直是完全懵掉,把定义、课件反复看了好多遍,结果题还是不会。动态规划适用于解决最优解问题,解决多阶段的决策问题。多阶段决策问题的求解过程可以分为若干个相互联系的阶段,在每一个阶段都需要作出决策,并影响到下一阶段的决策。在那些可供选择的策略中,选取一个最优策略,在预定的标准下达到最好的效果。最优性原理是不管初始状态和第一步决策是什么,余下的决策对于前一次决策所产生的新状态,构成最优决策序列;最优决策序列的子序列一定包含了最优决策子序列,包含非最优的决策子序列一定不是最优的决策序列。以每一步都是最优的来保证局部是最优的。该类问题求解的步骤,首先确定这个问题该用动态规划解决。然后描述一个最优解的结构,寻找子问题,对问题进行划分。再定义状态,将与子问题相关的各个变量一组取值定义为一个状态,若有k个变量,用k维数组存储各个状态下的解。找状态转移方程,从一个状态到另一个状态变量时变量值的改变。自底向下计算最优解。根据题意要求,看是否需要构建最优解的路径。记得当时做动态规划专题时,晕的不行,只会做几道最基础的题。当时动态规划专题里的题只有几个类型,但是稍微一变化就晕了。最长上升子序列、登山问题、合唱团排队问题、最长上升子序列和、最大子矩阵和、滑雪问题等等,看着都很相似,一做就晕,可能还没找到关键。当时课件看了好多遍,有些题思路都已经记下来了,模模糊糊好像懂了一点。然而,当我写这篇总结时,查找课件时,悲伤的发现我好像忘了个差不多了。悲伤,看来还要重看动态规划了。

然后学习的是背包问题,背包问题是一种特殊的动态规划,感觉比动态规划要简单。背包问题分为0-1背包,完全背包,多重背包,分组的背包问题。重点要区分的是0-1背包和完全背包循环的区别。0-1背包模板:for i=1…..n; for  v=v……0; f[v]=max{f[v],f[v-c[i]]+w[i]};体积是从大到小。完全背包模板:for=1……n;for  v=0…..v;f[v]=max{f[v],f[v-cost]+weight};体积为从小到大。背包问题的模式比较简单,思路比较固定。但有很多问题,直接用背包解法会超时。需要用贪心来解决。下一个学习的就是贪心。贪心算法是通过多次贪心选择,根据某种贪心标准,得到问题的最优解。贪心不是从整体上考虑问题,而是在局部寻找局部最优,而问题的特性又决定了局部最优即整体最优。贪心算法步步取最优使得它的运算量小,如果一个问题可以用多种方法解决,贪心算法无疑是最好的解决办法之一。有的贪心问题很简单,类似于简单的模拟就能做出来。但有的问题,如果背包和贪心结合就比较麻烦了。但更关键的问题是,有的题看不出来是贪心问题,根本不会朝着贪心方向想。记得省赛最后一道题,就是个贪心问题,但当时先想到的是背包,看了一会后又发现数据量太大,用背包很可能超时。本来给这道题剩的时间就不多,最后因为时间问题只能放弃。记得老师说过:“如果动态规划、背包都解决不了的问题,不妨朝贪心方向考虑一下。”暂时也只能这样了,对于某个问题是否能用贪心解决是一点谱都没有。

然后学习了二分查找,感觉这个专题是最友好的了,简单。处理数据也比较快捷。二分查找算法分为最基本的二分查找查找目标元素,查找函数值,切网线和分披萨,过河移除石头、切割数组等等。解决方法是在某一区间内查找元素,如果查找到了元素,结束;如果未查找到,目标元素在左边,更改上界,目标元素在右边,更改下界。特别要注意的是,对于double型数据的处理,处理精确度,一不小心就WA了。二分查找解决的问题是具有单调性的问题,可由此分开,分开讨论,解决三分问题。对于一些实际问题,当公式难以推导出来时,二分、三分法可以较为精确地求解出一些临界值,且效率也是令人满意的。

然后是搜索专题,搜索算法是利用计算机的高性能来有目的地穷举一个问题的部分或所有的可能的情况,从而求出问题的解的一种方法。搜索算法相对于单纯的枚举算法有了一定的方向性和目标性。算法是在解的空间中,从一个状态转移到其他状态,这样进行下去,将解的空间中的状态遍历,找到目标状态。每一个状态都是一个可能的解,状态的转移就是问题从一个状态转移到另一个状态,这样就可以进行搜索的一步步延伸,最后要得到的解也是其中的一个状态。根据不同的问题可以分为广度优先搜索和深度优先搜索,广度优先搜索用队列进行处理。深度优先搜索相当于递推问题,重在回溯。所有问题都可以用搜索解决,但是单纯的暴力搜索很容易超时,可以在搜索过程中适当地添加一些剪枝,减少运算。广度优先搜索可用于求最短队列和路径,搜索问题一般用于解决地图问题。广度优先搜索生成所有可能的状态,构成下一层节点,检查是否出现目标状态,顺序利用规则。深度优先搜索对一个节点搜索到底,看是否在搜索过程中出现目标状态。搜索专题中比较基础经典的题目,寻找@块。可以用广度优先搜索和深度优先搜索解决,但广度优先搜索的搜索次数多,会超时。现在做搜索专题的感觉就是难,道理理论我都懂,就是不知道该从哪里入手,该怎么搜索,现在只能是记模板,加强印象,理清思路。也许做着做着就会了,就渐入佳境了,但愿如此。

然后学习的专题是是数据结构,感觉还可以,知识点理解起来不是很难。也许是我还没开始做题,还没有接触到难题。数据结构包括栈、队列和树。栈只能在某一端插入和删除元素,后进先出。队列可在队列两端进行操作,先进先出。栈和队列的直接题目比较少,栈和队列一般作为一种工具辅助解题。广度优先搜索就是利用了队列先进先出特性,将需要进行搜索的点压入队列。检查表达式是否合法,括号的匹配问题,求表达式的值则应用了栈先进后出的特点。在树这方面,介绍了树的存储方式、树的遍历以及一种特殊的树形结构——二叉树。二叉树每个节点的度最多为2,一棵深度为k且有2^k-1各节点的树称为满二叉树。除了存储和遍历外,还可以对二叉树实现的操作有建立一棵二叉树、插入一个结点到二叉树中、删除结点或子树。堆结构是一种数组对象,是一棵完全二叉树。堆的主要操作是put向堆中加入一个元素,get从堆中取出并删除一个元素。堆的应用过程相当于STL中的优先队列。

最后一个专题是图论。课本上讲的比较简略,但直觉告诉我这章的题可能不太好做。后两个学习专题没有直接地刷题,但是这两个专题的内容让我更好地理解了前面的递推递归专题和搜索。数据结构中的二叉树让我对搜索过程更好地理解,学了二叉树之后,对素数环的回溯过程理解得更深了。图分为有向图和无向图,图可以用二维数组邻接矩阵存储,赋极大值表示不连通。图的遍历分为广度优先遍历和深度优先遍历,与广搜和深搜类似。一笔画问题每条边只遍历一次,哈密尔顿环每个点只能走一遍。可利用图论知识求最短路径,最优路径。

还有没有讲的数学部分,又是一个大难题,在做HDU上的80道题时,好多题都有涉及数学知识点。做到这部分时直接卡壳了,一道题卡好长时间,花式超时。然后去百度上搜数学知识点,再做题,好痛苦的感觉。而数学知识又那么多那么多,想想就头疼。难怪说学计算机的最重要的是数学要好,下一步是要填数学这个坑了。道路尚且漫长而艰难。

三、训练总结+省赛总结

在运动会+五一假期期间五天参加了训练,感受了一下比赛的氛围。第一天的时候,还是很不适应的,中午不吃饭可以忍,但是习惯了午睡,不睡觉很乏。十二点之后感觉大脑都停止转动了,整个是晕晕乎乎的。在训练过程中,大部分题目是和我没有关系的,因为连它想叫我干什么都看不懂。一开始以为这是语言问题,理解会有偏差,接触多了之后我发现我想多了,即使全部是用中文表述的,该看不懂的还是看不懂。训练时让我体会到了“舍”的重要,比赛时在没有思路的题上浪费再多时间也是徒劳。在训练时深刻地体会到了我的实现代码能力的不足,有些题看起来会,思路也比较正了,但具体实现时会有各种奇葩的错误出现。比如在一场训练中写代码,设立了三个结构体,结果忘记了创建结构体对象,一调调出十八个错误来,当时内心是很崩溃的。有些题有坑,修修改改是很正常的,但是编译时出现这么多错误,就的确是我的问题了。可能是基础真的太不咋地了,我想通过杭电上的ACM  steps尽力提高一下能力。做的题多了在实现代码中犯的低级错误自然就会减少。在训练时我差不多只负责读题和提供基本思路,至于具体的代码,全靠队友。辛苦队友,正也让我体会到了合作的重要性。就是为了以后不拖队友后腿也要好好努力,提升能力。

省赛就是一个比较神奇的经历,比赛前期做题磕磕绊绊,各种不顺。多亏在后期时放平了心态,对之前的错误代码修修补补,再封榜后神奇地又过了两道题。省赛的经历告诉了我几个道理1、合作很重要,大家集思广益才会想出更好的办法。2、任何时候不要放弃,最后时候也可能翻盘。3、不要失去从头再来的勇气,一定要有把代码全删了重写的决心。

在训练和省赛时,我也感受到了自己能力的缺乏。在训练和省赛过程中没有做出一道与算法有关的题目。做出来的都是水题和模拟题,知识面窄也有好处,就只能抱着那几道简单的题不放,各种可能的错误都想到,不停地修修补补。可长久下来这样根本不行,更熟练地应用算法解题才是目标。再次感谢队友,一直没放弃我,帮我分担了很多。

四、以后

想要继续走下去的很大一部分原因是因为不甘心,在ACM上已经付出了不少时间,但是学到的东西只是表面上的很浅的一层。不如再继续花时间在上面,多学点东西,真正的达到提升能力的目标。这条路不好走,我已经体会过了,但是我愿意走下去。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值