回文字符序列(编程之美2015资格赛)

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

描述

给定字符串,求它的回文子序列个数。回文子序列反转字符顺序后仍然与原序列相同。例如字符串aba中,回文子序列为"a", "a", "aa", "b", "aba",共5个。内容相同位置不同的子序列算不同的子序列。

输入

第一行一个整数T,表示数据组数。之后是T组数据,每组数据为一行字符串。

输出

对于每组数据输出一行,格式为"Case #X: Y",X代表数据编号(从1开始),Y为答案。答案对100007取模。

数据范围

1 ≤ T ≤ 30

小数据

字符串长度 ≤ 25

大数据

字符串长度 ≤ 1000

 

样例输入
5
aba
abcbaddabcba
12111112351121
ccccccc
fdadfa
样例输出
Case #1: 5
Case #2: 277
Case #3: 1333
Case #4: 127
Case #5: 17
递归超时算法:
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

char data[30];
int flag[30] = {0};
static int sum=0;
string str;

bool isRight(int datapos)
{
    int tempflag = true;
    for(int i = 0;i <= datapos/2; i++)
        if(data[i]!=data[datapos-1-i])
            tempflag = false;
    return tempflag;
}

void findPlan(int pos,int length)
{
    if(pos==length)
    {
        int datapos = 0;
        for(int i = 0;i < length; i++)
            if(flag[i]==1)
            {
                data[datapos] = str[i];
                datapos++;
            }
        if(isRight(datapos))
            sum++;
    }
    else
    {
        flag[pos] = 1;
        findPlan(pos+1,length);
        flag[pos] = 0;
        findPlan(pos+1,length);
    }
}

int main()
{
    int num;
    cin>>num;
    int i = 0;
    while(i<num)
    {
        cin>>str;
        int pos = 0,length;
        length = str.length();
        //for(int i = 0;i < length; i++)
        //    data[i] = str[i];
        sum = 0;
        findPlan(pos,length);
        cout<<"Case #"<<(i+1)<<": "<<(sum%100007)<<endl;
        i++;
    }

    return 0;
}

  

posted @ 2015-04-18 11:59  再见,少年  Views(816)  Comments(0Edit  收藏  举报