【USACO】calfflac

关键:以回文中心位置为变量进行遍历


//必须把纯字母先提出来 否则肯能会出现错误 比如: 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

时间: 2024-11-02 00:56:57

【USACO】calfflac的相关文章

【USACO】checker

一看题目 经典的8皇后问题 不过是皇后数量可变而已 不用想 回溯法. 需要个生成每次可选择序列的函数, 在存储可选择的序列时按照先大后小的顺序排的.这样每次找最小和去掉最小都很方便,只要有个记录数量的变量 每次减1就好了.  写完后,居然悲剧了. 在皇后数量达到13时, 在自己电脑上跑 内存溢出了 在评分系统上超时了.需要优化. #include <stdio.h> //k计算第几层从0开始 x已经摆好的位置 S存放产生的位置 l存放产生的数量 N一共有多少位置可以选择 int calcula

【USACO】milk3

倒牛奶的问题, 开始看感觉跟倒水的问题很像, 想直接找规律, 写个类似于循环取余的代码. 但后来发现不行,因为这道题有三个桶,水量也是有限制的.只好用模拟的方法把所有的情况都试一遍. 建一个state[21][21][21]的数组存储出现过的状态.对于遍历状态,对每一种状态, 分别采用六种处理方法,若有新状态出现这将新状态置为1,同时标记flag++:若所有循环之后,flag == 0, 就说明遍历完成了. 开始脑子抽筋了, 写了个多出口的程序, 显然是错的.如下: int mothersmil

【USACO】第一章总结

做了大半个月,终于把第一章做完了 有的题遇到了不小的坎儿,看着网上一群高中生都做得那么好,心理还是有些小郁闷的.不禁感慨我过去的四年真是虚度啊.总结一下第一章学习到的知识吧. ①闰年判断 int isleapyear(int N) { if((N%100 != 0 && N%4 ==0) || (N%400 == 0)) return 1; else return 0; } 计算闰年日期时可以用两个数组存放每个月的时间 int Year[12] = {31, 28, 31, 30, 31,

【USACO】Transformations

A square pattern of size N x N (1 <= N <= 10) black and white square tiles is transformed into another square pattern. Write a program that will recognize the minimum transformation that has been applied to the original pattern given the following l

【USACO】奶牛跑步2

P1443 - [USACO]奶牛跑步2 Description FJ的N(1 <= N <= 100,000)头奶牛们又兴高采烈地出来运动了!她们在一条无限长的小路上跑步,每头牛起跑的位置都不同,速度也不尽相同. 道路中划出了若干条跑道,以便她们能快速"超车",同一跑道中的任意两头牛都不会出现在相同的位置.不过FJ不愿让任何一头牛更换跑道或者调整速度,他想 知道如果让牛们跑足T(1 <= T <= 1,000,000,000)分钟的话,至少需要多少条跑道才能满

【USACO】beads

题目: You have a necklace of N red, white, or blue beads (3<=N<=350) some of which are red, others blue, and others white, arranged at random. Here are two examples for n=29: 1 2 1 2 r b b r b r r b r b b b r r b r r r w r b r w w b b r r b b b b b b

【USACO】ariprog

输入 : N  M 要找到长度为 N 的等差数列,要求数列中每个数字都可以表达成 a^2 + b^2 的和, 数字大小不超过M^2 + M^2 输出: 等差数列首元素 间隔 (多组答案分行输出) 解题思路:因为等差数列的数字都是平房和数  所以先生成所有的 从0 - M^2 + M^2的平方和数 去掉相同的并从小到大排序 然后对 所有间隔 . 首元素 做循环 判断能否找到以该首元素和间隔为条件的其他N-1个需要的数字 可以就存成答案: 提交后超时了.... test 5的时候 超了5s 正在想简

【USACO】Mother&#39;s Milk(搜索)

一开始还在想去重的问题,结果发现后台数据貌似没有重复的情况= = /* ID: 18906421 LANG: C++ PROG: milk3 */ #include<cmath> #include<cstdio> #include<vector> #include<algorithm> using namespace std; const int maxn = 25; int vis[maxn][maxn][maxn] = {0}; vector<in

【USACO】草地排水

Drainage Ditches 草地排水 usaco 4.2.1描述在农夫约翰的农场上,每逢下雨,Bessie最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间.因此,农夫约翰修建了一套排水系统来使贝茜的草地免除被大水淹没的烦恼(不用担心,雨水会流向附近的一条小溪).作为一名一流的技师,农夫约翰已经在每条排水沟的一端安上了控制器,这样他可以控制流入排水沟的水流量.农夫约翰知道每一条排水沟每分钟可以流过的水量,和排水系统的准确布局(起点为水潭而终点为小