2019亚洲区域赛徐州网络赛 D Carneginon KMP算法

https://nanti.jisuanke.com/t/41386
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 TT and the sequence on visitors’ licence is SS. For each visitor,

If the length of TT is longer than the length of SS, it’s obviously that the visitor is younger. And if SS is a substring of TT, Carneginon would call the visitor my child!. Otherwise, Carneginon would call the visitor oh, child!.

If the length of TT is less than the length of SS, it’s obviously that the visitor is elder. And if TT is a substring of SS, Carneginon would call the visitor my teacher!. Otherwise, Carneginon would call the visitor senior!.

Of course, if the length of TT is equal to the length of SS, the visitor is Carneginon’s peer. And if TT is equal to SS, 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 TT (Carneginon’s licence), qq (the number of visitors) and each visitor’s licence(S_iS
i

). Can you judge what Caneginon needs to say when he sees every visitor?

Input
The first line is a string TT, representing Carneginon’s license.

The second line is and integer qq, which means the number of visitors.

Then mm lines, for each line, there is a string SS, denoting the visitor’s license.

1 \leq |T| \leq 10^51≤∣T∣≤10
5
, 1 \leq |S| \leq 10^51≤∣S∣≤10
5
, 1 \leq q \leq 10001≤q≤1000

It is guaranteed that q \times (|S|+|T|) \leq 10^7q×(∣S∣+∣T∣)≤10
7
.

Output
There are qq lines.

For each SS, output what Carneginon should say correctly.

样例输入 复制
abcde
6
abcde
aaaaa
abcd
aaaa
abcdef
abccdefg
样例输出 复制
jntm!
friend!
my child!
oh, child!
my teacher!
senior!
题目大意:给一个字符串 T T T q q q个字符串 S S S,对于每一个 S S S,(1) T T T的长度大于 S S S的长度,若 S S S T T T的子串,输出 m y   c h i l d ! my\ child! my child!,否则输出 o h ,   c h i l d ! oh, \ child! oh, child!。(2) T T T的长度小于 S S S的长度,若 T T T S S S的子串,输出 m y   t e a c h e r ! my \ teacher! my teacher!,否则输出 s e n i o r ! senior! senior!。(3) T T T的长度等于 S S S的长度,若 T T T S S S相等,输出 j n t m ! jntm! jntm!,否则输出 f r i e n d ! friend! friend!

思路:也是签到题。 K M P KMP KMP算法就行了,数据范围都暗示了。

#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;

char s[2][100005];
int Next[2][100005];

void getnext(int op)
{
	int i=0,k=-1,m=strlen(s[op]);
	Next[op][0]=-1;
	while(i<m-1)
	{
		if(k==-1||s[op][i]==s[op][k])
		{
			if(s[op][++i]==s[op][++k])
				Next[op][i]=Next[op][k];
			else
				Next[op][i]=k;
		}
		else
			k=Next[op][k];
	}
}

int kmp(int op)
{
	int i=0,j=0,t=op^1;
	int n=strlen(s[t]),m=strlen(s[op]); //m 模板串
	while(i<n&&j<m)
	{
		if(i==-1||s[t][i]==s[op][j])
			++i,++j;
		else
			i=Next[op][i];
	}
	if(i==n)
		return j-i+1;
	else
		return -1;
}

int main()
{
	scanf("%s",s[0]);
	getnext(0);
	int n;
	scanf("%d",&n);
	int len1=strlen(s[0]),len2;
	while(n--)
	{
		scanf("%s",s[1]);
		len2=strlen(s[1]);
		if(len1>len2)
		{
			if(kmp(0)!=-1)
				printf("my child!\n");
			else
				printf("oh, child!\n");
		}
		else if(len1==len2)
		{
			bool flag=0;
			int i=0,j=0;
			while(i<len1)
			{
				if(s[0][i]==s[1][j])
					++i,++j;
				else
				{
					flag=1;
					break;
				}
			}
			if(flag)
				printf("friend!\n");
			else
				printf("jntm!\n");
		}
		else
		{
			getnext(1);
			if(kmp(1)!=-1)
				printf("my teacher!\n");
			else
				printf("senior!\n");
		}
	}
	return 0;
}

你可能感兴趣的:(比赛补题,KMP)