2012年2月4日
摘要: POJ_3294 首先,我们可以把这几个序列合并成一个序列,并且在之间加入一些分隔符,但这些分隔符最好用不一样的且不同于序列中的字符的整数表示,这样在后面寻找后缀间的公共前缀时就避免了把分隔符也匹配进去的情况。 接着,我们只要二分字符串的长度k,并依height[]的值将height[]看成若干组,每组中height[]的值均不小于k。如果这一组中涵盖的不同的序列的数量大于N/2,那么就说明满足题意的字符串的长度至少为k。 找到k的值后再遍历一遍height数组,将符合要求的前缀的首字符的位置记录下来即可,根据首字符的位置和k的值就可以输出满足题意的字符串了。同时,由于是遍历height数组, 阅读全文
posted @ 2012-02-04 19:22 Staginner 阅读(278) 评论(0) 推荐(0) 编辑
摘要: POJ_2774 这个题目实际上就是去求最长公共子串,如果用gets读字符串会WA,所以还得用scanf。 首先,我们可以把两个字符串合并,并在中间加一个’$’以避免某个公共前缀同时在两个字符串中。用后缀数组的做法处理出height数组后,扫描一遍height[],如果sa[i-1]和sa[i]的位置分别在两个字符串中且height[i]大于max的话,就更新一下max。最后输出max的值即可。 可以证明,这样求得的解是合理的。对于合并后的字符串的后缀i、j,不妨设i<j,且i的首字符在第一个字符串里,j的首字符在第二个字符串里面,假设i、j的最长公共前缀为k,对于按字典序排好的各个后缀 阅读全文
posted @ 2012-02-04 13:10 Staginner 阅读(297) 评论(0) 推荐(0) 编辑
摘要: URAL_1297 找回文串最直观的一个算法就是枚举中间的点,然后向两边查找,看最后能拓展多远,但是这样是n^2的算法,利用后缀数组可以达到O(nlogn)的复杂度。其实在枚举中间的点之后,向外拓展多远是取决于两个方向相反的字符串的公共前缀的,而如果利用后缀数组我们就可以在O(logn)的时间内找到这两个字符串公共前缀最长是多少。 下面面临的一个问题就是两个字符串是方向相反的,为了能够使两个字符串同向,我们可以把原序列翻过来的序列插入到原序列后面,这样这个字符串里面顺序看过去就既包含了原序列的正向的字符串,同时也包含了原序列的反向的字符串。 但是,如果这样去找后缀间的公共前缀的话,我们会发.. 阅读全文
posted @ 2012-02-04 10:26 Staginner 阅读(431) 评论(0) 推荐(0) 编辑