UVA 12333 - Revenge of Fibonacci (斐波那契的复仇) 【后日谈】by SuCicada
正篇以及正确解题思路和代码参见 UVA 12333 - Revenge of Fibonacci (斐波那契的复仇) by SuCicada 此篇为后日谈 要说为什么专门开一篇来记录想法呢,主要是因为想说的太多了。首先从UVA的提交记录上来看,上一次答题是在足足1年之前了。 这么久以来都没有再好好做算法,感觉快要忘本了。而且出来之后脑子也不是那么灵光了,虽然更理性,但是却少了些抽象的想象力。 再说这道题,一开始我根本不知道什么字典序,完全是打表暴力比对的。把前40位算出来那里都是没错的。 但是之后我想的是:用map排个序,然后二分查找。但是这样会有问题,因为二分找到的可能并不是最小的,所以找到之后还需要分别找到同样匹配前缀的那一区域的数字,因为是map排过序的,所以他们都是挨着的。 但是之后在极端痛苦了两个晚上之后,我放弃了这种做法,经过测试计算,发现我电脑中g++在一秒钟可以进行4亿次运算,假设有5万个40位数字需要比对,4亿除以5万除以40 有20万呢,或者保险点我们取个1000。(一直到当时我都以为这道题的时间限制是1秒) 然后我就在死灰复燃的状态下在下2天晚上把位数比对写出了(暴力)。为了减少比对量,我打表了前3位,也就是记录下前三位的数字第一次出现的序数,而且这个序数是map中的序数,map中的序数和fibo的序数可是不同的。 而且map不能随机读取,怎么办,我又创造了两个数组专门存放键和值。 后来我还发现个位数的搜索起来比较慢,因为他们要暴力比对的数是最多的,所以我又用一个map来记录已经查找过的结果。 我真的是要疯,一直到昨天晚上我把这套模型整通。本地一跑,通过,time测下来 1.2秒,我巨喜。提交,time limit exceeded。把udebug上的样例全部跑了一遍,没有超过1.5秒的。我随机生成各种5万个数的组合,2秒之内绝对能过。 但是 time limit exceeded, time limit exceeded,time limit exceeded,time limit exceeded,time limit exceeded。 ”难道是表打的太小了?“我又将打表位数升到4,升到5。然而为什么更慢了。 那会已经3点钟了,我感到生命力的衰减,在极度无望的情况下,我打开百度,UVA 12333,我真特么被这道题23333了, 这道题考大数+字典树 我惊住,一个新的窗子仿佛打开了,一查,全懂了,完全懂了。我缩在床上颤抖不已,脑子瞬间就明白了我该怎么做,但是身体已经无法支撑下去,为了能保持住自己的生命力。我艰难的进入睡眠。 第二天我写,真的很快,因为我已经知道了,虽然遇到了oj离奇而严厉的 runtime error错误。但是我很冷静,因为我知道这个方法肯定是没错的,这条路一定是对的。就是这种知道目的的坚定。 当Accepted出现在屏幕上,我想哭了。太痛苦了,太刺激了,太疯狂了。再加上17个小时没有进食带来的虚弱感让我恍惚,感觉我活下来了。 劫后余生的感激之情。 而现在已经5点怅然若失感时不时在席卷我,跨时两个星期,4个夜晚的崩溃,20余小时的挣扎,20多次的错误。我太弱了,我为我的弱小感到伤心,但是我又为我的成功感到高兴。 算法拯救我,算法伤害我,算法摧残我,算法安慰我。 我时尝为我的自艾感到痛苦。 但是我害怕痛苦吗,不如说我正喜欢痛苦。 附赠更快的却更错的代码: #include<iostream> #include<algorithm> #include<iterator> #include<vector> #include<string> #include<cstdio> #include<iomanip> #include<map> #include<cmath> #include<cstring> using namespace std; vector<string> fibonacci(100005); map<string,int> fiboSorted; vector<string> fiboName(100005); vector<int> fiboIndex(100005); int limitSite = 52; string add(string a,string b){ int aLen = a....