《每日一题: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; }