好位置(思维)

链接:https://ac.nowcoder.com/acm/problem/15870
来源:牛客网

题目描述

给出两个串s和x
定义s中的某一位i为好的位置,当且仅当存在s的子序列y=sk1sk2....sk|x|1<=k1<k2<...<k|x|<=|s|)y=sk1sk2....sk|x|(1<=k1<k2<...<k|x|<=|s|) 满足y=x且存在j使得i=kj成立。
问s中是否所有的位置都是好的位置。

输入描述:

一行两个字符串s,x,这两个串均由小写字母构成。
1 <= |s|, |x| <= 200000

输出描述:

Yes表示是。No表示不是。

具体思路:

pre[i]代表字符串x的前缀中,以s[i]结尾的子串中,字符串s从1~i中所能包含的以s[i]结尾的子串的最长长度。

suf[i]代表字符串x的后缀中,以s[i]开头的子串中,字符串s从i~len(s)中所能包含的以s[i]结尾的子串的最长长度。

AC代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 # define ll long long
 4 # define inf 0x3f3f3f3f
 5 const int maxn = 2e5+100;
 6 int pre[maxn],suf[maxn];
 7 char str1[maxn],str2[maxn];
 8 int vis[maxn];
 9 int main()
10 {
11     scanf("%s",str1+1);
12     scanf("%s",str2+1);
13     int len1=strlen(str1+1);
14     int len2=strlen(str2+1);
15     int pos=1,ans=0;
16     for(int i=1; i<=len1; i++)
17     {
18         if(str1[i]==str2[pos]&&pos<=len2)
19         {
20             ans++;
21             pos++;
22             vis[str1[i]]=ans;
23             pre[i]=ans;
24         }
25         else
26         {
27             pre[i]=vis[str1[i]];
28         }
29     }
30     memset(vis,0,sizeof(vis));
31      pos=len2,ans=0;
32     for(int i=len1; i>=1; i--)
33     {
34         if(str1[i]==str2[pos]&&pos>=1)
35         {
36             ans++;
37             pos--;
38             vis[str1[i]]=ans;
39             suf[i]=ans;
40         }
41         else
42         {
43             suf[i]=vis[str1[i]];
44         }
45     }
46     int flag=1;
47     for(int i=1; i<=len1; i++)
48     {
49        // printf("%d %d %d\n",i,pre[i],suf[i+1]);
50         if(pre[i]+suf[i]<len2)flag=0;
51     }
52     if(flag)
53     printf("Yes\n");
54     else printf("No\n");
55     return 0;
56 }

 

 

posted @ 2019-05-22 17:48  Let_Life_Stop  阅读(453)  评论(0编辑  收藏  举报