USACO-cha1-sec1.3(AOJ-133) Calf Flac

来源:互联网 发布:sql server 2012 r2 编辑:程序博客网 时间:2024/06/09 15:27
Calf Flac
Time Limit: 1000 ms   Case Time Limit: 1000 ms   Memory Limit: 64 MB
Judge By Case
Description
It is said that if you give an infinite number of cows an infinite number of
heavy-duty laptops (with very large keys), that they will ultimately produce
all the world's great palindromes. Your job will be to detect these bovine beauties.

Ignore punctuation, whitespace, and case when testing for palindromes, but
keep these extra characters around so that you can print them out as the
answer; just consider the letters `A-Z' and `a-z'.

Find any largest palindrome in a string no more than 20,000 characters long.
The largest palindrome is guaranteed to be at most 2,000 characters long before
whitespace and punctuation are removed.

Input
A file with no more than 20,000 characters.

Output
The first line of the output should be the length of the longest palindrome found.
The next line or lines should be the actual text of the palindrome (without any
surrounding white space or punctuation but with all other characters) printed on a line
(or more than one line if newlines are included in the palindromic text). If there are
multiple palindromes of longest length, outputthe one that appears first.

Sample Input
OriginalTransformed
Confucius say: Madam, I'm Adam.

Sample Output
OriginalTransformed
11Madam, I'm Adam

Source
USACO 2002 winter
——————————————————分割线线割分——————————————————
思路:最长回文子串。不过,要命的是格式要求非常严格。参照白书关于回文子串的写法。首先考虑两个问题:1.只对字母进行判断,忽略输入格式,输出的时候保留首尾两个字母之间的子串格式  2.回文。
机器那么笨,在它的角度上想,(奇数——)应该先看第一个字,然后记住,接着看第二个字,记住,然后第三个字假如和第一个一样,说明回文了。否则还是记住。看第四个是不是和第二个一样,一样的话再看第五个跟第一个是不是一样。(偶数——)应该一直看到某个字出现两次,然后前后比较。
(终于看完了?以上思路是不好的。)

然而,人脑在判断的时候是怎么做的?扫一眼,从最可疑的地方向两边看。
模拟一下。每次看到一个数字,就向它两边查看下去。直到左右两端不同。先在奇数下模拟,再偶数。对偶数要注意了。
代码如下:
#include<stdio.h>#include<string.h>#include<ctype.h>char buf[20010],s[20010];int p[20010];int main(){int n, m = 0, maxi = 0, x, y, i = 0;int fx, fy;char c;while((c = getchar())!=EOF)  buf[i++] = c;//这种处理考虑到了字符串中包含回车符的情况buf[i] = '\0';n = strlen(buf);for(i = 0; i < n; i++)        if(isalpha(buf[i])){//isalpha这个函数判断是否为字母,是,返回1            p[m] = i;//p[]数组保存每个字母的下标            s[m++] = toupper(buf[i]);//toupper将字母全部变成大写再返回  }    s[m] = '\0';    for(i = 0; i < m; i++) {        for(int j = 0; i-j>=0 && i+j<m; j++){//回文长度也许是奇数?            if(s[i-j] != s[i+j])  break;            if(j*2+1 > maxi){                maxi = j*2 + 1;                x = p[i-j];                y = p[i+j];            }        }        for(int j = 0; i-j>=0 && i+j+1<m; j++){//回文长度也可能是偶数?注意!“某个字母出现两次”这个起始条件是通过j=0时s[i-j]和s[i+j+1]恰好相邻实现的            if(s[i-j] != s[i+j+1])  break;            if(j*2+2 > maxi){                maxi = j*2 + 2;                x = p[i-j];                y = p[i+j+1];            }        }    }printf("%d\n", maxi);for(i = x; i <= y; i++)  putchar(buf[i]);printf("\n");    return 0;}


0 0
原创粉丝点击