10.24 test2 T1

监听的宇宙电波可以抽象成1个长度为 L 的小写字母组成的字符串。
同时在三体⼈总结出来了 n 段敏感电波的样⼦,每段敏感电波的长度 都是 m。 现在请你实现⼀个程序,求出在这长度为 L 的小写字母组成的字符串 中某个敏感电波第1次出现的位置(位置从 1 开始计数)。 如果从头到尾,没有任何敏感电波出现,输出”no”(不带双引号)。

思路 hash

  1. 把L拆分成每m一段,在n里二分这个值

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef unsigned long long ull;  
int read()
{
	char ch=' ';
	int f=1;int x=0;
	while(ch<'0'||ch>'9')
	{
		if(ch=='-') f=-1;ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
	    x=x*10+ch-'0';ch=getchar();
	}
	return x*f;
}
const int N=1e4+100;
const int M=1e5+100;
const int base=27;
const int p=1e9+7;
ull bit[100];
ull hsum[N];
char a[N][100];
char s[M];
ull ssum[M];
ull geth(int l,int r)
{
	return (ssum[r]-ssum[l-1]*bit[r-l+1]%p+p)%p;
}
int main()
{
	int l,n,m;
	l=read(),n=read(),m=read();
	bit[0]=1;
	int i,j;
	for(i=1;i<=m;i++)
	{
		bit[i]=bit[i-1]*base%p;
	}
	for(i=1;i<=n;i++)
	{
		scanf("%s",a[i]+1);
		for(j=1;j<=m;j++)
		{
			hsum[i]=(hsum[i]*base%p+a[i][j]-'a')%p;
		}
	}
	sort(hsum+1,hsum+1+n);
	scanf("%s",s+1);
	for(i=1;i<=l;i++)
	{
		ssum[i]=(ssum[i-1]*base%p+s[i]-'a')%p;
	}
	for(i=1;i+m-1<=l;i++)
	{
		ull x=geth(i,i+m-1);
		int pos=lower_bound(hsum+1,hsum+1+n,x)-hsum;
		if(hsum[pos]==x)
		{
			cout<<i<<endl;
			return 0;
		}
	}
	cout<<"no"<<endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42110318/article/details/83341902