Problem Description
Carneginon was a chic bard. But when he was young, he was frivolous and had joined many gangs. Recently, Caneginon was to be crowned, because the king was shocked by his poems and decided to award him the gold medal lecturer. Therefore, Most of people in the Kingdom came to visit him.
However, as a medal lectirer, Carneginon must treat the visitors kindly, including elders and younger generations. In order to maintain order, every visitor received a license with a magic field engraved on it. And the magic field on the licence was made up of lowercase letters.
Carneginon had a unique licence, which could judge whether others are his older or younger. Now, we assume that the sequence on Carneginon's licence is T and the sequence on visitors' licence is S. For each visitor,
- If the length of T is longer than the length of S, it's obviously that the visitor is younger. And if S is a substring of T, Carneginon would call the visitor my child!. Otherwise, Carneginon would call the visitor oh, child!.
- If the length of T is less than the length of S, it's obviously that the visitor is elder. And if T is a substring of S, Carneginon would call the visitor my teacher!. Otherwise, Carneginon would call the visitor senior!.
- Of course, if the length of T is equal to the length of S, the visitor is Carneginon's peer. And if T is equal to S, it shows that the visitor entered through an improper way and Carneginon would shout jntm!. Otherwise, Carneginon would call the visitor friend!.
Now, you know the T (Carneginon's licence), q (the number of visitors) and each visitor's licence(Si). Can you judge what Caneginon needs to say when he sees every visitor?
Input
The first line is a string T, representing Carneginon's license.
The second line is and integer q, which means the number of visitors.
Then mm lines, for each line, there is a string S, denoting the visitor's license.
1≤∣T∣≤105, 1≤∣S∣≤105,1≤q≤1000
It is guaranteed that q×(∣S∣+∣T∣)≤107.
Output
There are q lines.
For each S, output what Carneginon should say correctly.
Sample Input
abcde
6
abcde
aaaaa
abcd
aaaa
abcdef
abccdefgSample Output
jntm!
friend!
my child!
oh, child!
my teacher!
senior!
题意:
给出一个模式串 T,再给出 k 个文本串,对于每个文本串:
- 如果 T、S 的长度一样,若 S 与 T 的相同,输出 jntm!,否则输出 friend!
- 如果 T 的长度大于 S 的长度,若 S 是 T 的子串,输出 my child!,否则输出 oh, child!
- 如果 T 的长度小于 S 的长度,若 S 是 T 的子串,输出 my teacher!,否则输出 senior!
思路:KMP 裸题
首先预处理出模式串 T 的 next 数组,然后对于每个文本串 S,求其长度与 T 进行比较,根据题意利用 KMP 进行判断
Source Program
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<bitset>
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
#define Pair pair<int,int>
LL quickPow(LL a,LL b){ LL res=1; while(b){if(b&1)res*=a; a*=a; b>>=1;} return res; }
LL quickModPow(LL a,LL b,LL mod){ LL res=1; a=a%mod; while(b){if(b&1)res=(a*res)%mod; a=(a*a)%mod; b>>=1;} return res; }
LL getInv(LL a,LL mod){ return quickModPow(a,mod-2,mod); }
LL GCD(LL x,LL y){ return !y?x:GCD(y,x%y); }
LL LCM(LL x,LL y){ return x/GCD(x,y)*y; }
const double EPS = 1E-10;
const int MOD = 1E9+7;
const int N = 100000+5;
const int dx[] = {-1,1,0,0,-1,-1,1,1};
const int dy[] = {0,0,-1,1,-1,1,-1,1};
using namespace std;
int Next[N];
void getNext(char p[]){
Next[0]=-1;//初始化
int len=strlen(p);//模式串长度
int j=0;//模式指针j
int k=-1;//位置k
while(j<len) {
if(k==-1||p[j]==p[k]) {//Next[j+1]=Next[j]+1
k++;//此前有Next[j]=k
j++;//指针后移
if(p[j]==p[k])//当两个字符相等时跳过
Next[j]=Next[k];
else
Next[j]=k;
}else{
k=Next[k];
}
}
}
int KMP(char t[],char p[]) {
int tLen=strlen(t);//文本串长度
int pLen=strlen(p);//模式串长度
int i=0;//文本串指针
int j=0;//模式串指针
while(i<tLen&&j<pLen) {
if (j==-1||t[i]==p[j]){//当j为-1时,要移动的是i,同样j也要归零
i++;
j++;
}
else{
j=Next[j];//j回到指定位置
}
}
if(j==pLen)//最终当模式串的位置与模式串的长度相同时,说明匹配成功
return i-j;
else//匹配失败
return -1;
}
char T[N],S[N];
int main(){
int n;
scanf("%s",T);
scanf("%d",&n);
getNext(T);
while(n--){
scanf("%s",S);
int Tlen=strlen(T);
int Slen=strlen(S);
if(Tlen==Slen){
if(!strcmp(T,S))
printf("jntm!\n");
else
printf("friend!\n");
}
else if(Tlen>Slen){
if(KMP(T,S)!=-1)
printf("my child!\n");
else
printf("oh, child!\n");
}
else{
if(KMP(S,T)!=-1)
printf("my teacher!\n");
else
printf("senior!\n");
}
}
return 0;
}