zoj 2744 Palindromes(计算回文子串个数的优化策略)

题目链接:

  http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2744

题目描述:

  A regular palindrome is a string of numbers or letters that is the same forward as backward. For example, the string "ABCDEDCBA" is a palindrome because it is the same when the string is read from left to right as when the string is read from right to left.

Now give you a string S, you should count how many palindromes in any consecutive substring of S.

Input

There are several test cases in the input. Each case contains a non-empty string which has no more than 5000 characters.

Proceed to the end of file.

Output

A single line with the number of palindrome substrings for each case.

Sample Input

aba
aa

Sample Output

4
3

 1 /*问题 求一个字符串的回文子串的个数
 2 解题思路 首先弄明白一个字符串的子串的个数,比如abaa,子串有a,b,a,a,ab,aba,abaa,aba,ab。
 3 一般的解题思路是找出所有子串一一判断,但是当字符串很长的时候可能会出现超时错误。
 4 现提供一种优化策略:
 5 对于一个串来说,如果该串的中心保证回文才能保证以该中心为基础的扩展串是回文串,换句话说,只要该串的中心
 6 不是回文则直接判定向外扩展的串没有一个回文串,直接结束扩展。
 7 具体实现比较考验耐心,具体的数带入几个串计算一下即可。*/ 
 8 #include <cstdio>
 9 #include <cstring>
10 
11 int main()
12 {
13     char str[5010];
14     int half,left,right,i,len,count;
15     while(scanf("%s",str) != EOF)
16     {
17         count=0;
18         len=strlen(str);
19         for(i=0;i<=len-2;i++){//钉住最后一个字符,从左往右
20             half=(len-1-i)/2;
21             if((len-i) & 1)//该串长度为奇数
22             {
23                 left=i+half-1;
24                 right=left+2;
25             } 
26             else//该串长度为偶数
27             {
28                 left=i+half;
29                 right=left+1;
30             }
31             while(left>=i){
32                 if(str[left] == str[right]){
33                     count++;
34                     left--;
35                     right++;
36                 }
37                 else
38                     break;
39             } 
40         }
41         
42         for(i=len-2;i>=1;i--){//钉住第一个字符,从右往左
43             half=i/2;
44             if(i+1 & 1)//该串长度为奇数
45             {
46                 left=half-1;
47                 right=left+2;
48             } 
49             else//该串长度为偶数
50             {
51                 left=half;
52                 right=left+1;
53             }
54             while(left>=0){
55                 if(str[left] == str[right]){
56                     count++;
57                     left--;
58                     right++;
59                 }
60                 else
61                     break;
62             }
63         }
64         printf("%d\n",len+count);
65     }
66     return 0;
67 } 

 

posted @ 2018-03-11 12:04  Reqaw  阅读(356)  评论(0编辑  收藏  举报