Carneginon(2019 ACM-ICPC 徐州赛区网络赛 D)

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
abccdefg

Sample 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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值