《每日一题:4月2日》预处理加速
月月查华华的手机
https://ac.nowcoder.com/acm/problem/23053
对于这个字符串,很明显直接暴力查询,复杂度会TLE。
所以我们考虑预处理出下一次跳转的位置。
因为一共就26个字母,所以我们可以定义.
dp[i][j].表示i位置后面第一个'a'+j字符的位置.
很显然,如果我们要跳转要跳去第一个后面的这个字符的位置。
Code:
#include<iostream>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<math.h>
#include<stack>
#include<map>
#include<limits.h>
#include<vector>
#include<string.h>
#include<string>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 1e6+5;
const int M = 5*1e5+5;
#define pi acos(-1)
#define INF 1e9
#define INM INT_MIN
#define pb(a) push_back(a)
#define mk(a,b) make_pair(a,b)
#define dbg(x) cout << "now this num is " << x << endl;
#define met0(axx) memset(axx,0,sizeof(axx));
#define metf(axx) memset(axx,-1,sizeof(axx));
#define sd(ax) scanf("%d",&ax)
#define sld(ax) scanf("%lld",&ax)
#define sldd(ax,bx) scanf("%lld %lld",&ax,&bx)
#define sdd(ax,bx) scanf("%d %d",&ax,&bx)
#define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx)
#define sfd(ax) scanf("%lf",&ax)
#define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx)
#define pr(a) printf("%d\n",a)
#define plr(a) printf("%lld\n",a)
map<char,int> mp;
int dp[N][30];
int main()
{
char s[N];
scanf("%s",s+1);
int len = strlen(s+1);
for(int i=len;i>=1;--i)
{
for(int j=0;j<26;++j)
{
dp[i][j] = mp['a'+j];
}
mp[s[i]] = i;
}
int n;sd(n);
for(int i=0;i<n;++i)
{
string ff;
cin >> ff;
int j = 1,let = ff.size();
int ii = (ff[0] == s[1]?1:dp[1][ff[0]-'a']);
if(ii == 0)
{
printf("No\n");
continue;
}
while(j < let)
{
if(dp[ii][ff[j]-'a'] == 0) break;
ii = dp[ii][ff[j]-'a'];
j++;
}
if(j == let) printf("Yes\n");
else printf("No\n");
}
system("pause");
return 0;
}
查看6道真题和解析

