zoukankan      html  css  js  c++  java
  • 1040. Longest Symmetric String (25)

    题目例如以下:

    Given a string, you are supposed to output the length of the longest symmetric sub-string. For example, given "Is PAT&TAP symmetric?", the longest symmetric sub-string is "s PAT&TAP s", hence you must output 11.

    Input Specification:

    Each input file contains one test case which gives a non-empty string of length no more than 1000.

    Output Specification:

    For each test case, simply print the maximum length in a line.

    Sample Input:
    Is PAT&TAP symmetric?
    
    Sample Output:
    11
    


    题目要求推断最长的回文,有两种思路可供选择。

    思路一,从两头进行推断,定义两个指针start_index和end_index分别指向头部和尾部,首先固定start_index,让end_index从最后一个元素向前遍历,直到碰到start_index。其间对start_index到end_index的范围进行回文推断,回文推断的规则非常easy,假设start和end指向的元素一样,回文长度length=2,然后start+1。end-1,继续比較,假设符合则继续+2。直到start<end不再满足,注意在这之中仅仅要有一次不符合start指向的元素不等于end指向的元素,累加的长度length都是无效的。都应当输出1。注意一种情况。假设形如abba这种形式。跳出循环时start = 2、end = 1,length = 4满足条件。可是假设是形如aba这种形式。start=end=1,length=2。不能得到正确结果,这时候应当推断是否start==end而且length!=1,则说明是回文、且须要修正,这时候把length+1就可以得到正确结果。


    注意一个问题。为了能输入空格。使用getline(cin,str)来输入字符串。

    代码例如以下:

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    string str;
    
    int isRevese(int s, int e){
        int length = 1;
        while(s < e){
            if(str[s] != str[e]) return 1;
            s++;
            e--;
            if(length == 1) length = 2;
            else length += 2;
        }
    
        if(length != 1 && s == e) length++;
    
        return length;
    
    }
    
    int main()
    {
        getline(cin,str);
    
        int start_index = 0;
        int end_index = str.length() - 1;
        int max_length = -1;
        int len = 0;
    
        for(start_index = 0; start_index < str.length(); start_index++){
            for(end_index = str.length() - 1; end_index >= start_index; end_index--){
                len = isRevese(start_index,end_index);
                if(len > max_length){
                    max_length = len;
                }
            }
        }
        cout << max_length << endl;
        return 0;
    }

    思路二,採用中心枚举法,以每一个字符为中心向两端枚举,这种方法最大的问题在于枚举时对于形如abba的处理十分棘手,由于不管列举哪个b,都不能找到以b为中心的回文。而其实abba就是回文。

    这里我看到了sunbaigui的巧妙解法,他把全部的字符前面都加一个前导-1,这样通过以-1为中心枚举就能够得到正确的回文了,比如abba变为-1a-1b-1b-1a,通过中间的-1。得到了整个序列,这时候的回文长度是正确长度的2倍,仅仅须要除以2就可以得到正确结果。

    这里直接贴的是sunbaigui的代码,欢迎去到他的博客。

    #include<iostream>
    #include<string.h>
    #include<vector>
    
    #define Max 10000
    int dp[2*Max+1];
    char str[Max];
    
    int mmax(int a, int b)
    {
    	if(a > b) return a;
    	else return b;
    }
    int main()
    {
    	while(gets(str))
    	{
    		//memset(dp, -1, sizeof(dp));
    		int len = strlen(str);
    		//insert special character into str, must not appeared in str
    		std::vector<int> magic;
    		for(int i = 0; i < len; ++i)
    		{
    			magic.push_back(-1);//special character
    			magic.push_back(str[i]);//character to int
    		}
    		magic.push_back(-1);
    		//enumerate center point for magic vector
    		len = (int)magic.size();
    		int max = 1;
    		for(int i = 1; i < len; ++i)
    		{
    			int l, r;
    			int step = 1;
    			for(l = i-1, r = i+1; l >= 0 && r < len; l--, r++)
    			{
    				if(magic[l] != magic[r])
    					break;
    				step += 2;
    			}
    			max = mmax(max, step);
    		}
    
    		printf("%d
    ", max/2);
    	}
    	return 0;
    }


  • 相关阅读:
    hdu1074Doing Homework
    1088滑雪
    hdu1078FatMouse and Cheese
    hdu1058Humble Numbers
    hdu1114 Piggy-Bank
    hdu1069Monkey and Banana
    未解决的问题_c#中,最小化触发事件
    WPF Button 样式资源设置&后台生成button样式
    .NET 调用外部exe程序,出现已停止工作
    json类序列化与反序列化参考
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/6918867.html
Copyright © 2011-2022 走看看