Hidden String
Accepts: 437
Submissions: 2174
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 262144/262144 K (Java/Others)
问题描述
今天是BestCoder一周年纪念日. 比赛管理员Soda有一个长度为
n
的字符串
s
. 他想要知道能否找到
s
的三个互不相交的子串
s[l1..r1]
,
s[l2..r2]
,
s[l3..r3]
满足下列条件:
1.
1≤l1≤r1<l2≤r2<l3≤r3≤n
2.
s[l1..r1]
,
s[l2..r2]
,
s[l3..r3]
依次连接之后得到字符串"anniversary".
输入描述
输入有多组数据. 第一行有一个整数
T
(1≤T≤100)
, 表示测试数据组数. 然后对于每组数据:
一行包含一个仅含小写字母的字符串
s
(1≤|s|≤100)
.
输出描述
对于每组数据, 如果Soda可以找到这样三个子串, 输出"YES", 否则输出"NO".
输入样例
2
annivddfdersewwefary
nniversarya
输出样例
YES
NO
题目意思很明白,考虑将"anniversary"分割成三段,计算每段在母串中是否成功匹配,如果成功匹配,就可以返回yes。
枚举所有将anniversary分割的可能方法,对每一个都做判断即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int n,m,p,q;
char ch[] = "anniversary";
char str[120];
struct node //每个node里面是一种分割方式。
{
char sub1[15];
char sub2[15];
char sub3[15];
int len1;
int len2;
int len3;
void calculate()
{
int lenj = len1+len2;
int lenk = 11;
for(int i =0;i<len1;i++)
sub1[i] = ch[i];
for(int i = 0,j = len1; j< lenj;i++,j++)
sub2[i] = ch[j];
for(int i = 0,k = len1+len2; k < lenk;i++,k++)
sub3[i] = ch[k];
};
}S[50];
int main()
{
int cnt = 0;
for(int i =1 ; i <= 9; i++) //枚举三段的长度
{
for(int j = 1; j <= 10 - i; j++)
{
int k = 11 - i - j;
S[cnt].len1 = i;
S[cnt].len2 = j;
S[cnt].len3 = k;
S[cnt].calculate(); //根据每段的长度计算出三段子串
cnt++;
}
}
// for(int i =0; i<=44;i++)
// printf("%d %s %s %s\n",i,S[i].sub1,S[i].sub2,S[i].sub3);
int T;
cin>>T;
while(T--)
{ memset(str,'\0',sizeof(str));
scanf("%s",str);
int flag = 0;
for(int m = 0; m <= 44; m++)
{
node temp = S[m];
int flag1 = 0, flag2 = 0, flag3 = 0;
int i=0,j=0; //i为母串指针,j为字串指针
while(1) //匹配第一个子串
{
if (i >= 100) break;
if(str[i] == temp.sub1[j])
{
int ok = 1;
for (int k = 1; k < temp.len1; k++)
{
i++,j++;
if (str[i] != temp.sub1[j])
{ok = 0;break;}
}
if (ok == 0) { j = 0;continue;}
else {flag1 = 1;break;}
}
else
{
i++;
}
}
// printf("%d %d %d\n",flag1,i,j);
if (flag1 == 0) continue;
i++;j = 0;
while(1) //匹配第二个子串
{
if (i >= 100) break;
if(str[i] == temp.sub2[j])
{
int ok = 1;
for (int k = 1; k < temp.len2; k++)
{
i++,j++;
if (str[i] != temp.sub2[j])
{ok = 0;break;}
}
if (ok == 0) { j = 0;continue;}
else {flag2 = 1;break;}
}
else
{
i++;
}
}
// printf("%d %d %d\n",flag2,i,j);
if(flag2 == 0 ) continue;
i++;j = 0;
while(1) //匹配第三个子串
{
if (i >= 100) break;
if(str[i] == temp.sub3[j])
{
int ok = 1;
for (int k = 1; k < temp.len3; k++)
{
i++,j++;
if (str[i] != temp.sub3[j])
{ok = 0;break;}
}
if (ok == 0) { j = 0;continue;}
else {flag3 = 1;break;}
}
else
{
i++;
}
}
// printf("%d %d %d\n",flag3,i,j);
if(flag3 == 0 ) continue;
if (flag1 && flag2 && flag3) {flag = 1; break;}
}
if (flag)
printf("YES\n");
else printf("NO\n");
}
return 0;
}