Hidden StringTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 1434 Accepted Submission(s): 514
Problem Description
Today is the 1st anniversary of BestCoder. Soda, the contest manager, gets a string
s
of length
n
. He wants to find three nonoverlapping substrings
s[l1..r1]
,
s[l2..r2]
,
s[l3..r3]
that:
1. 1≤l1≤r1<l2≤r2<l3≤r3≤n 2. The concatenation of s[l1..r1] , s[l2..r2] , s[l3..r3] is "anniversary".
Input
There are multiple test cases. The first line of input contains an integer
T
(1≤T≤100)
, indicating the number of test cases. For each test case:
There's a line containing a string s (1≤|s|≤100) consisting of lowercase English letters.
Output
For each test case, output "YES" (without the quotes) if Soda can find such thress substrings, otherwise output "NO" (without the quotes).
Sample Input
Sample Output
|
题意:给你一个字符串,让你从中找出s1[l1, r1]、s2[l2, r2]、s3[l3,r3]三段子串组成字符串anniversary,且三段子串满足l1 <= r1 <= l2 <= r2 <= l3 <= r3。问你能不能找到这样的三段子串。
思路:对字符串anniversary,每次枚举字符串中两个分割点i 和 j,分别构成三个相应的子串,查找在文本串中是否存在。
注意查找成功后,要重新构建文本串。
AC代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int f[10];
char ss[] = {"anniversary"};
char str[210], str1[210], str2[210];
void getfail(char *P)
{
int l = strlen(P);
f[0] = f[1] = 0;
for(int i = 1; i < l; i++)
{
int j = f[i];
while(j && P[i] != P[j])
j = f[j];
f[i+1] = P[i] == P[j] ? j + 1 : 0;
}
}
int Find(char *T, char *P)//在字符串T中 查找字符串P
{
int l1 = strlen(T);
int l2 = strlen(P);
int j = 0;
for(int i = 0; i < l1; i++)
{
while(j && T[i] != P[j])
j = f[j];
if(T[i] == P[j])
j++;
if(j >= l2)
return i+1;//返回最后匹配位置
}
return -1;
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%s", str);
bool flag = false;
char s[10];
int p, pos;
for(int i = 1; i <= 9; i++)//第一分割点
{
if(flag)
break;
for(int j = i; j <= 9; j++)//第二分割点
{
//截取第一个字符串
p = 0;
for(int k = 0; k < i; k++)
s[p++] = ss[k];
s[p] = '\0';
getfail(s);//求失配函数
if(Find(str, s) != -1)//查找
{
pos = Find(str, s);
p = 0;
int len = strlen(str);
for(int k = pos; k < len; k++)//重构文本串
str1[p++] = str[k];
str1[p] = '\0';
}
else
continue;
//截取第二个字符串
p = 0;
for(int k = i; k <= j; k++)
s[p++] = ss[k];
s[p] = '\0';
getfail(s);
if(Find(str1, s) != -1)
{
pos = Find(str1, s);
p = 0;
int len = strlen(str1);
for(int k = pos; k < len; k++)//重构文本串
str2[p++] = str1[k];
str2[p] = '\0';
}
else
continue;
//截取第三个
p = 0;
for(int k = j+1; k < 11; k++)
s[p++] = ss[k];
s[p] = '\0';
getfail(s);
if(Find(str2, s) != -1)
{
flag = true;//第三个成功就 ok了
break;
}
}
}
if(flag)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}