题目大意:
给出一个字符串,求出最长的回文串,如果有多种答案的话,按字典序最小输出。
思路:
刚开始没有看清楚就直接正序逆序求最长公共子序列,结果发现是错的。
后来参考了别人的代码发现,求出最长公共子序列的思路是正确的,但是呢,可能出现特例
例如:
kfclbckibbibjccbej
jebccjbibbikcblcfk
bcibbibc是他们的最长公共子序列,但是这并不是一个回文串,但是前面一半肯定是回文串的前半部分,所以只要逆序就可以求出后面的半部分。但是要注意要分回文串的长度是奇数或者偶数来处理。
发现自己对于输出这一部分真的很弱。。
代码:
#include <iostream>
using namespace std;
#include <stdio.h>
#include <cstring>
const int MAXN = 1010;
char str1[MAXN],str2[MAXN];
int n,len;
struct node {
int len;
string str;
}f[MAXN][MAXN];
int main() {
while(gets(str1 + 1)) {
len = strlen(str1 + 1);
for(int i = 1; i <= len ; i++) {
str2[i] = str1[len - i + 1];
}
for(int i = 0; i <= len; i++) {
f[0][i].len = 0;
f[0][i].str = "";
}
for(int i = 1; i <= len; i++) {
for(int j = 1; j <= len; j++) {
if(str1[i] == str2[j]) {
f[i][j].len = f[i - 1][j - 1].len + 1;
f[i][j].str = f[i - 1][j - 1].str + str1[i];
}
else {
if(f[i - 1][j].len > f[i][j - 1].len) {
f[i][j].len = f[i - 1][j].len;
f[i][j].str = f[i - 1][j].str;
}
else if(f[i][j - 1].len > f[i - 1][j].len) {
f[i][j].len = f[i][j - 1].len;
f[i][j].str = f[i][j - 1].str;
}
else {
f[i][j].len = f[i - 1][j].len;
f[i][j].str = min(f[i][j - 1].str,f[i - 1][j].str);
}
}
}
}
int maxlen = f[len][len].len;
string ans = f[len][len].str;
if(maxlen & 1) {// jishu
for(int i = 0; i < maxlen/2; i++)
printf("%c",ans[i]);
for(int i = maxlen/2; i >= 0; i--)
printf("%c",ans[i]);
printf("\n");
}
else {
for(int i = 0; i < maxlen /2; i++) {
printf("%c",ans[i]);
}
for(int i = maxlen/2 - 1; i >= 0; i--)
printf("%c",ans[i]);
printf("\n");
}
}
return 0;
}