1. 程式人生 > >10.24 test2 T1

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