先声明,我这个解法并不是标准的回文串,但是在poj上一直是WA,所以总是哪里是有问题的,但是很尴尬的是,自己测试是没有问题的。。。
所以写出来自己梳理一下,如果哪位网友路过帮我看看也是非常非常之感谢
首先呢看一下题目要求的回文结构,最直接的想法就是遍历每一个字符,依次作为中心,然后看这种情况下所需补充的最少字符数
那如何计算最小字符数呢,我的想法是设立两个指针,分别指向对称中心左右两边,然后向外移动指针,通过对比指针指向判断是增加一个符号构成对称还是继续移动
所以最后的情况是至少有一个指针到达了边界,这个时候另一个指针剩下的符号就要全部插入以便构成回文,所以就有了以下的代码
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
int len;
int max;
cin >> len;
max = len - 1;
cin >> s;
for (int i = 1; i < len-1; i ++){
int j = i-1, k = i+1, temp = 0;
while(j>=0){
while (k<len){
if ( s[j] == s[k] ){
j --; k ++;
}
else{
k ++;
temp ++;
}
}
if (k>=len) break;
}
if ( j+1 ) temp += j + 1;
if ( len-k ) temp += len - k;
if ( temp<max ) max = temp;
}
cout << max << endl;
return 0;
}
但是这个代码是有一点问题的,就是它是以一个数字为中心,两边对称的结构,这是不全面的,另一种情况是以两个数之间的空隙为中心,额这样可能不太好理解,举个例子
1233 以数为中心,最小插入为3,即构成1233321 / 1323231 / 3123213,但以空隙为中心,则最小插入为2,即构成123321
这个改起来也很方便,调整指针的位置就好了,代码如下
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
int len;
int max;
cin >> len;
max = len - 1;
cin >> s;
for (int i = 1; i < len-1; i ++){
int j = i-1, k = i+1, temp1 = 0;
while(j>=0){
while (k<len){
if ( s[j] == s[k] ){
j --; k ++;
}
else{
k ++;
temp1 ++;
}
}
if (k>=len) break;
}
if ( j+1 ) temp1 += j + 1;
if ( len-k ) temp1 += len - k;
j = i, k = i+1;
int temp2 = 0;
while(j>=0){
while (k<len){
if ( s[j] == s[k] ){
j --; k ++;
}
else{
k ++;
temp2 ++;
}
}
if (k>=len) break;
}
if ( j+1 ) temp2 += j + 1;
if ( len-k ) temp2 += len - k;
int temp = 0;
if ( temp1>temp2) temp = temp2;
else temp = temp1;
if (temp<max) max = temp;
}
cout << max << endl;
return 0;
}
我发的时候我以为自己已经解决了,可是tm提交了之后还是报错,真是拿衣服,现在还是WA我也是没辙了。。。
其实我觉得要是超时我都可以接受,毕竟将近N3的时间复杂度,可是WA哦我的天。。。
期待什么时候脑洞大开想出来吧
于是我又回来了,换了另一种方法。。。嗯。。。就是网上流传的那种。。。
具体的思路可以看他的文章啦,但是代码是我自己写的,大家也是看得出来的啦
#include <iostream>
#include <string>
using namespace std;
int main()
{
int n;
cin >> n;
string s1;
cin >> s1;
string s2 = s1;
for (int i = 0; i < n; i ++)
s2[i] = s1[n-i-1];
int c[2][5001];
int temp = 0;
memset(c,0,sizeof(c));
for (int i = 1; i <= n; i ++)
for ( int j = 1; j <= n; j ++){
temp = c[(i-1)%2][j]>c[i%2][j-1]?c[(i-1)%2][j]:c[i%2][j-1];
if (s1[i-1] == s2[j-1])
c[i%2][j] = (c[(i-1)%2][j-1]+1)>temp?(c[(i-1)%2][j-1]+1):temp;
else
c[i%2][j] = temp;
}
int max = c[0][n]>c[1][n]?c[0][n]:c[1][n];
cout << n-max << endl;
return 0;
}
所以那个AC是多么的不容易。。。