关键:以回文中心位置为变量进行遍历
//必须把纯字母先提出来 否则肯能会出现错误 比如: lvlv= 在检查长度4时 lvlv认为不是回文 vlv=认为是回文 但实际上 lvl 出现的要更早一些
//判断回文的方法 可以输入字符串后 左右比较 或者分别正序 逆序 存储 判断是否相等
//我的思路不对 严重超时了 我是以长度为变量进行循环 对于每个长度 每一个不同起始点的序列都需要对 整个序列重新判断一次是否为回文 O(n^3)
//答案中 以中心字母为变量进行循环 只需要对每一个字母做为中心变量遍历一次, 每次的遍历长度小于等于总序列长度 通过不断更新存储最长回文找到最优解 O(n^2)
#include <stdio.h>
#include <string.h>
#include <ctype.h>
typedef struct
{
char c;
int n;
}AZ;int isch(char c)
{
return ((c <= ‘z‘ && c >= ‘a‘) || (c >= ‘A‘ && c <= ‘Z‘));
}
int iscalfflac(AZ *c, int l, int r, int * loc) //输入字符 和 左右边界 判断是否为回文
{
int len = r - l + 1;
int ll, rr;
int flag = 1;
int is = 0; //判断是否进入过相等 防止纯符号
while(l <= r)
{
if(c[l].c == c[r].c || c[l].c == c[r].c - ‘A‘ + ‘a‘ || c[r].c == c[l].c - ‘A‘ + ‘a‘)
{
l++; r--; is++;
}
else
{
flag = 0;break;
}
}
return (flag == 1) ? 1 : 0;
}
int main()
{
FILE *in, *out;
int loc[4] = {0,0,0,0};
int i = 0, j = 0, length;
int r, l, rr, ll;
char c[20000], c1[20000], c2[20000], c3[20000], c4[20000];
AZ ch[20000];
in = fopen("calfflac.in", "r");
out = fopen("calfflac.out", "w");
while(fscanf(in, "%c", &c[i]) != EOF)
{
if(isch(c[i]))
{
ch[j].c = c[i];
ch[j].n = i;
j++;
}
i++;
}
length = j; //总输入长度
for(i = 0; i < length; i++)
{
if(isupper(ch[i].c))
{
ch[i].c = ch[i].c - ‘A‘ + ‘a‘;
}
c1[i] = ch[i].c;
c2[length - i - 1] = ch[i].c;
}for(i = length; i > 0; i--) //这种方法在大输入时严重超时了
{
for(l = 0; l <= length - i; l++ )
{
r = l + i - 1;
if(iscalfflac(ch, l, r, loc) == 1)
{
fprintf(out, "%d\n", i);
for(j = ch[l].n ; j <= ch[r].n; j++)
{
fprintf(out, "%c", c[j]);
}
fprintf(out, "\n");
return 0;
}
}
}
fprintf(out, "%d\n", 0);
return 0;
}
下面是答案的,注意做中心点时要对 奇数 偶数 考虑齐全
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>char fulltext[21000];
char text[21000];char *pal;
int pallen;void
findpal(void)
{
char *p, *fwd, *bkwd, *etext;
int len;etext = text+strlen(text);
for(p=text; *p; p++) {
/* try palindrome with *p as center character */
for(fwd=bkwd=p; bkwd >= text && fwd < etext && *fwd == *bkwd;
fwd++, bkwd--)
;
bkwd++;
len = fwd - bkwd;
if(len > pallen) {
pal = bkwd;
pallen = len;
}/* try palindrome with *p as left middle character */
for(bkwd=p, fwd=p+1;
bkwd >= text && fwd < etext && *fwd == *bkwd; fwd++, bkwd--)
;
bkwd++;
len = fwd - bkwd;
if(len > pallen) {
pal = bkwd;
pallen = len;
}
}
}void
main(void)
{
FILE *fin, *fout;
char *p, *q;
int c, i, n;fin = fopen("calfflac.in", "r");
fout = fopen("calfflac.out", "w");
assert(fin != NULL && fout != NULL);/* fill fulltext with input, text with just the letters */
p=fulltext;
q=text;
while((c = getc(fin)) != EOF) {
if(isalpha(c))
*q++ = tolower(c);
*p++ = c;
}
*p = ‘\0‘;
*q = ‘\0‘;findpal();
fprintf(fout, "%d\n", pallen);
/* find the string we found in the original text
by finding the nth character */
n = pal - text;
for(i=0, p=fulltext; *p; p++)
if(isalpha(*p))
if(i++ == n)
break;
assert(*p != ‘\0‘);/* print out the next pallen characters */
for(i=0; i<pallen && *p; p++) {
fputc(*p, fout);
if(isalpha(*p))
i++;
}
fprintf(fout, "\n");exit(0);
}
【USACO】calfflac,布布扣,bubuko.com