Problem Description
女神邀请众ACdream开联欢会,显然作为ACM的佼佼者,气球是不能少的~。女神准备了三种颜色的气球,红色,黄色,绿色(交通信号灯?)
有气球还不能满足女神,女神要在气球上写字。
写什么好呢~?字符串神马的最有爱了~
女神先拿出一个字符串,然后把字符串的每一个真·前缀写到了黄色气球上面,每一个真·后缀写到了绿色气球上面,每一个真·子串写到了红色气球上面。
对于一个字符串s[1...n],真·前缀为s[1...i](1<=i<n)·,真·后缀为s[j...n](1<j<=n),真·子串为s[i...j](1<i<=j<n)
于是女神就得到了好多好多的气球~
那么在同时出现在三种颜色的气球上的字符串中,最长是什么?
神马,404 not found? 找不到这样的字符串?女神很生气!那就只好输出"angry goddess"了。(不包括双引号,注意大小写,中间有一个空格)
Input
多组数据,每组数据一行字符串,长度不超过100000,
Output
对于每组数据,输出一个字符串
Sample Input
abcabcabc aaaaaaaaa abcabc
Sample Output
abc aaaaaaa angry goddess 解题思路: 其实这题就是求,一个字符串中有没有三个相同的子串,这三个字串必须一个是 s1[0..i<n-1],s2[0<i....j<n-1],s3[0<j....n-1],刚开始的做法是直接用kmp算法一个一个搜符合条件的,但是由于数据很大超时,最后想到了next数组的原理正好他的值就是前后缀相等的个数,只要再找出与中间的next[i]相等的就符合条件了,当然这一个也是最大的串,首先将len=next[strlen(ab)],从最后往前找,找到符合条件的就结束,可以输出结果,找不到就就len=next[len],不然会超时!如果没有找到一个,那么这个结束条件是len=-1或者=0
AC代码:
#include <iostream> #include <algorithm> #include <stdio.h> #include <string.h> #include <stdlib.h> using namespace std; char ab[100005]; char nb[100005]; int next[100005]; void getNext(char *nb) { int j=0,k=-1; next[0]=-1; while(j<strlen(nb)) { if(k==-1||nb[j]==nb[k]) { j++; k++; next[j]=k; } else k=next[k]; } } int main() { int i,temp,max1; while(gets(ab)) { temp=0;max1=0; strcpy(nb,ab); getNext(nb); int len=next[strlen(ab)]; while(len!=0&&len!=-1) { for(i=2;i<strlen(ab)-1;i++) { if(len==next[i]) { temp=1;break; } } if(temp) break; len=next[len]; } if(!temp) printf("angry goddess"); for(i=0;i<len;i++) { printf("%c",ab[i]); } cout<<endl; } return 0; }
时间: 2024-10-29 03:14:50