您的位置:首页 > 编程语言

编程之美2015 资格赛 hihocoder 题目2: 回文字符序列

2015-04-17 21:06 447 查看
思路:暴力搜,用BFS的方式,生成每一种可能,再对每一种可能进行判断是否回文,进行统计。严重超时!计算一个25个字符的,大概要20多秒!

#include <iostream>
#include <string>
#include <stdio.h>
#include <memory>
#include <string.h>
using namespace std;
long long map[1001][1001];
int pos[26];
int tmp[130];
int len;
string input;
void cal(int start ,int end)
{
if(start==end)      //自己到自己,即单个字符的情况,是回文,也就是它自己
{
map[start][end]=1;
return ;
}
if(end-start==1)    //两个字符的情况,判断两者是否相同。若相同,则有3个,否则,只有两个
{
if(input[start]==input[end])
map[start][end]=3;
else
map[start][end]=2;
return ;
}
map[start][end]+=map[start][end-1]+1;   //先加一个,也就是他自己单独作为回文串。

/*
for(int i=end-1; i>=start; i--)
{
if(input[i]==input[end])            //考虑end之前的每一个,对于第i个,如果和end相同,那么结果就是i到end之间的串的回文串的最大数量+1
map[start][end] += map[i+1][end-1]+1;       //状态方程
}
*/
int temp = pos[end];
while( temp>-1 && temp>=start )
{
map[start][end] += map[temp+1][end-1]+1;       //状态方程
temp = pos[temp];
}

map[start][end]%=100007;
}

void sao()
{
for(int i=0; i<26; i++)
pos[i] = -1;        // -1说明第1个字符的前面并没有与其相同的字符。
for(int i=0; i<130; i++)    //记录最近一个字符出现的位置
tmp[i] = -1;

for(int i=0; i<len; i++)
{
pos[i] = tmp[input[i]];
tmp[input[i]] = i;       //更新字符input[i]最新出现的位置
}
}

int main()
{
//freopen("input.txt","r",stdin);
int T;
int Case=0;
cin>>T;

while(T--)
{
memset(map,0,sizeof(map));

cin>>input;
len = input.size();
sao();
for(int i=0; i<input.size(); i++)   //从左往右扫
{
for(int j=i; j>=0; j--)         //从第i个开始往左扫,才能保证在计算大问题之前,所要依靠的小问题已经被解决
{
cal(j,i);
}
}
cout<<"Case #"<<++Case<<": "<<map[0][input.size()-1]<<endl;
}

}


AC了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: