题目链接:点击这里
首先解决“判断时忽略标点,输出进却要按原样”的问题?
可以用一个简单的方法:预处理。构造一个新字符串,不包含原来的标点符号,而且所有字符变成大写(顺便解决了大小写的问题)。用到的函数:
- 用来检查c是否为字母,如果是字母,则返回1;否则返回0。
- 用来检查c是否为数字(0~9),如果是数字,则返回1;否则返回0。
- 用来将c字符转换为大写字母,返回c对应的大写字母。
- 用来将c字符转换为小写字母,返回c对应的小写字母。
最后的问题:原样输出。
由于在求 值时,不知道 和 在原串 中的位置。因此,必须增加一个数组 ,用 保存 在 中的位置。在预处理得到,然后在更新 的同时把 和 保存到 和 ,最后输出 到 中的所有字符。
#include<iostream>
#include<algorithm>
#include<string>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
const int MOD = 10000007;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
const int maxn = 5010;
char buf[maxn], s[maxn];
int p[maxn]; //新串下标到原字符串下标的映射
int dp[maxn][maxn];
int main()
{
gets(buf);
int lenb = strlen(buf);
int len = 0;
for(int i = 0; i < lenb; ++i)
{
if(isalpha(buf[i])) //字母
{
s[len] = toupper(buf[i]);
p[len] = i;
len++;
}
if(isdigit(buf[i])) //数字
{
s[len] = buf[i];
p[len] = i;
len++;
}
}
// printf("%d\n", len);
// for(int i = 0; i < len; ++i)
// printf("%c", s[i]);
// printf("\n");
int start = 0;
int maxx = 1;
for(int i = 0; i < len; ++i)
{
dp[i][i] = 1;
if(i<len-1&&s[i]==s[i+1])
{
dp[i][i+1] = 1;
start = i;
maxx = 2;
}
}
for(int L = 3; L <= len; ++L)
{
for(int i = 0; i + L - 1 < len; ++i)
{
int j = i + L - 1;
if(s[i]==s[j]&&dp[i+1][j-1]==1)
{
dp[i][j] = 1;
start = i;
maxx = L;
}
}
}
// printf("%d %d\n", start, maxx);
for(int i = p[start]; i <= p[start+maxx-1]; ++i)
printf("%c", buf[i]);
return 0;
}