站外题TLE求调 题目:
题目描述
给一个字符串 s(从一个环上的某点切开得到),其长度为n×k(由 n 个长度为 k 的子串拼成),以及 t 个互不相同的长度为 k 的字符串,问能否从这 t 个字符串中选出 n 个,按一定顺序首尾相接,拼成原环(如果可以,依次打印出第 i 个使用的字符串的序号)。 数据保证如果可以,只有一种符合条件的情况。 输入描述 第一行两个数 n,k。 第二行一个长度为 n×k 的字符串。 第三行一个数 t。 接下来 t 行,每行一个长度为 k 的字符串。 输出描述 如果可以,第一行输出 YES,第二行按顺序输出字符串编号。 如果不行,输出NO。
输入样例1
3 1
abc
4
b
a
c
d
输出样例1 YES
2 1 3
输入样例2
4 2
aabbccdd 4
dd
ab
bc
cd
输出样例2
NO
数据范围 对于100% 数据:t×k≤1e6 且 t≥n
TLE代码:
#include <bits/stdc++.h>
using namespace std;
int n,k,t,h,h1,s[100005],hh[100005],ans[100005],cnt=0;;
const int p=1e9+7;
map<int ,int>ht;
string s2,s1;
int main() {
cin>>n>>k;
cin>>s2;
s2+=s2;
int len=s2.size();
for(int j=0; j<len; j++) {
h=h*29+s2[j]-'a'+1;
h%=p;
s2[j]=h;
}
cin>>t;
for(int i=1; i<=t; i++) {
cin>>s1;
h1=0;
int len1=s1.size();
for(int j=0; j<len1; j++) {
h1=h1*29+s1[j]-'a'+1;
h1%=p;
}
hh[i]=h1;
ht[h1]=i;
}
bool f=0;
for(int i=1; i<=n; i++) {
for(int j=1;j<=t;j++){
if(hh[j]==s[i+k-1]-pow(p,k)*s[i-1]){
ans[++cnt]=h;
}
}
if(cnt==n){
f=1;
break;
}
}
if(f==0){
cout<<"NO"<<"\n";
}
else{
cout<<"YES"<<"\n";
for(int i=1;i<=cnt;i++){
cout<<ans[i]<<" ";
}
cout<<'\n';
}
return 0;
}
感谢大佬