Final Results
-- case number --
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
dance2 * * * * * * * * * *
hexagon * x * x x * x * * x x x x x x x
treats * * * * * * * * * *
时间分配:
读题花了大概半小时,第一题是括号匹配问题,第二题是模拟题,第三题是BFS。大概的思路有了,接下来开始编写程序了。
这三道题中最难的应是第三题,于是决定先做第三题。
第三题:hexagon
难点1:怎么去保存这张表
只能用数组保存了,就把图中的格点都下沉,像个小房子的数组;
难点2:怎样实现数字与图中对应
用了预处理实现数组坐标和数字之间的映射
难点3:怎样找相连的边
这个地方要考虑仔细一点,因为边界情况有点复杂。
最多也就六个相连的点,暴力一下,分别算出来;
难点4:怎样处理左右相邻不同的情况
具体联系题目中的图,要分三种情况去想,做的时候本想偷懒,把中间的合并到两边去了,但是不对的,在补赛完后才发现了。
第二题:treats
难点1:读题
题目的文字叙述比较多,所以要仔细不要漏掉细节;
难点2:怎样去实现
如果每次找一个不被挑过的最大的,则时间代价太大,达到O(n^5);
可以另外给排序,从大到小依次取,但就涉及到保存表的问题,要能把信息还原回去,我是用空间换时间,开了1,000,000的两个数组,映射回去值对应的坐标;由于表是在进行着动态交换的,所以两个大数组也要动态更新,还好更新不难;最后是怎么交换的问题,由于行优先,所以要先去找可以往前移的行去交换,然后在去找可以往前移的列交换;基于每次肯定要靠前移,被占用的行和列肯定是连续的,所以保存一个指针,指向当前可以交换的最小行列,就可以判断交换是否可以进行,但是这个指针也是要动态更新的,有些点可以本身不需要交换,但是他们也会占有相应的行列;
第一题:dance2
难点1:效率
如果真的老老实实去一对一对括号拆的话,编程复杂度较高,可能用指针实现会好些;但时间效率是比较低的;
由于题目没有要求给出组合的方式,所以可以利用括号的一些性质,由于括号的形式是<>(题目中是><),所以在任何地方<的个数不会比>的个数少,否则只能往><的方向发展了;最后两个方向个数要一致,就一定有一种方案可以配对了(证明??)
至于证明,可以用数学归纳法吧:
(1)当有n = 1对时,肯定是<>,存在配对方案;
(2)假设当n = k对时,存在配对方案;
当n = k+1是,易知第一个和最后一个一定是<,从左向右在位置i找到第一个>,则1 —— i-1都是<,把i-1和i配对,则剩下的一串仍此前所给符合要求,且有k对,由(2) 知,存在配对方案;
(4)综上符合上述条件的必存在一种配对方案。
心得:
1.造数据寻找BUG是十分重要的;
2.在一段程序前加COMMENT会使程序思路会清晰很多;
3.慢慢适应用中间结果方式分块检查程序的正确性;
4.大数组放在主函数外,其余尽量放在主函数内,循环变量在循环体内声明;
5.自信点,不要以为什么都不会证明,第一题的证明还是在能力范围内的,要去尝试;
6.数据范围还欠仔细,应该卡着估计,不应该放着估计,最后再适当加点;有的时候是数量级的估计错误;
7.if <> else <>嵌套小心忘记 else
My Code
hexagon.cpp
treats.cpp
dance2.cpp