码迷,mamicode.com
首页 > 其他好文 > 详细

HihoCoder

时间:2016-05-08 19:48:34      阅读:237      评论:0      收藏:0      [点我收藏+]

标签:

#1032 : 最长回文子串  20160508

时间限制:1000ms
单点时限:1000ms
内存限制:64MB

描述

   小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进。

   这一天,他们遇到了一连串的字符串,于是小Hi就向小Ho提出了那个经典的问题:“小Ho,你能不能分别在这些字符串中找到它们每一个的最长回文子串呢?”

   小Ho奇怪的问道:“什么叫做最长回文子串呢?”

   小Hi回答道:“一个字符串中连续的一段就是这个字符串的子串,而回文串指的是12421这种从前往后读和从后往前读一模一样的字符串,所以最长回文子串的意思就是这个字符串中最长的身为回文串的子串啦~”

   小Ho道:“原来如此!那么我该怎么得到这些字符串呢?我又应该怎么告诉你我所计算出的最长回文子串呢?

   小Hi笑着说道:“这个很容易啦,你只需要写一个程序,先从标准输入读取一个整数N(N<=30),代表我给你的字符串的个数,然后接下来的就是我要给你的那N个字符串(字符串长度<=10^6)啦。而你要告诉我你的答案的话,只要将你计算出的最长回文子串的长度按照我给你的顺序依次输出到标准输出就可以了!你看这就是一个例子。”

提示一 提示二 提示三 提示四
样例输入
3
abababa
aaaabaa
acacdas
样例输出
7
5
3

 个人认为这篇博客分析的比较好,虽然我是按照提示一步一步写出来的。

提交时发现必须在头尾加入两个不同的特殊字符,我下面这种方式没有在头尾加,提交we了,没想明白(详见代码中/**/注释的那一段)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        InputStreamReader isr = new InputStreamReader(System.in); 
        BufferedReader br = new BufferedReader(isr);
        String s = "";
        while ((s = br.readLine()) != null) {
            int t = Integer.parseInt(s);
            for (int i = 0;i < t;i++) {
                String str = br.readLine();
                StringBuilder sb = new StringBuilder();
                sb.append("$#");
                //在原字符串每个相邻字符串中间插入‘#‘
                for (int j = 0;j < str.length();j++) {
                    sb.append(str.charAt(j)+"#");
                }
                sb.append("&");  
                str = sb.toString();
/*把添加特殊字符那一段修改一下就不对了,没想明白,我看出来的现象是必须在头尾加入两个不同的特殊字符,
我下面这种方式没有在头尾加,提交we了
    

//在原字符串每个相邻字符串中间插入‘^‘
for (int j = 0;j < str.length()-1;j++) {
sb.append(str.charAt(j)+"^");
}
sb.append(str.charAt(str.length()-1));
str = sb.toString();


*/
int ans = 1,maxj = 0,maxjk = 0,pos = 0; int[] ls = new int[str.length()]; for (int j = 0;j < str.length();j++) { //获得当前j为中心的回文子串的最小长度 int k = 0; if (2*maxj-j < 0) { k = Math.min(0, ls[maxj]-2*(j-maxj))/2; } else { k = Math.min(ls[2*maxj-j], ls[maxj]-2*(j-maxj))/2; } k = k > 0 ? k : 0; ls[j] += 2*k+1; k++; while (((j-k) >= 0) && ((j+k) < str.length())) { if (str.charAt(j-k) == str.charAt(j+k)) { ls[j] += 2; //记录以每一个字符为中心时的最大回文长度 if (j+k > maxjk) { maxj = j; //记录使右边界最大的j maxjk = j+k; //记录右边界的最大值 } k++; } else { break; } } //更新最大回文子串长度与中心字符的位置 if (ls[j] > ans) { ans = ls[j]; pos = j; } } //去掉其中的特殊字符‘^‘ if (pos % 2 == 0) { if (ans >= 3) { ans = ans-2*((ans-3)/4+1); } } else { ans = ans-2*((ans-1)/4)-1; } System.out.println(ans); } } } }

 

 

HihoCoder

标签:

原文地址:http://www.cnblogs.com/fisherinbox/p/5471155.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!