2019南昌邀请赛网络预选赛 M. Subsequence

传送门

题意:

  给出一个只包含小写字母的串 s 和n 个串t,判断t[i]是否为串 s 的子序列

  如果是,输出"YES",反之,输出"NO";

坑点:

  二分一直TLE可还行;

  

具体思路+细节看代码(有点累了,不想写了)

AC代码:

扫描二维码关注公众号,回复: 5965359 查看本文章
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<vector>
 4 #include<cstring>
 5 using namespace std;
 6 #define mem(a,b) memset(a,b,sizeof(a))
 7 const int maxn=1e5+50;
 8 
 9 int n;
10 char s[maxn];
11 char ch[maxn];
12 int res[30];
13 vector<int >v[30];
14 /**
15     字母a~z转化为0~25
16     v[i]:i对应的字母在s中出现的所有位置
17     例如s="aabaa"
18     v[0]:0,1,2,3
19     v[1]:2
20 */
21 
22 bool isSat()
23 {
24     mem(res,0);
25     int cur=-1;
26     int len=strlen(ch);
27     for(int i=0;i < len;++i)
28     {
29         int x=ch[i]-'a';
30         //在s串中找x出现的位置 > cur 的第一个位置
31         //res[x]记录之前x到达的最远位置,没有这个数组,TLE到死
32         while(res[x] < v[x].size() && v[x][res[x]] <= cur)
33             res[x]++;
34         //没找到,返回false
35         if(res[x] == v[x].size())
36             return false;
37         cur=v[x][res[x]];//更新cur
38     }
39     return true;
40 }
41 void Solve()
42 {
43     int len=strlen(s);
44     for(int i=0;i < 30;++i)
45         v[i].clear();
46     for(int i=0;i < len;++i)
47         v[s[i]-'a'].push_back(i);
48 
49     for(int i=1;i <= n;++i)
50     {
51         scanf("%s",ch);
52         if(isSat())//判断串ch是否为串s的子序列
53             printf("YES\n");
54         else
55             printf("NO\n");
56     }
57 }
58 int main()
59 {
60     while(~scanf("%s",s))
61     {
62         scanf("%d",&n);
63         Solve();
64     }
65     return 0;
66 }
View Code

 将32,33行的whlie()代码改成二分查找后,反而慢了,真是搞不懂哟,莫非,出题放的数据就是在卡二分???

更改后的isSat()函数:

 1 int BS(int l,int r,int x,int val)
 2 {
 3     while(r-l > 1)
 4     {
 5         int mid=(l+r)/2;
 6         if(v[x][mid] >= val)
 7             r=mid;
 8         else
 9             l=mid;
10     }
11     return r;
12 }
13 bool isSat()
14 {
15     mem(res,-1);
16     int cur=-1;
17     int len=strlen(ch);
18     for(int i=0;i < len;++i)
19     {
20         int x=ch[i]-'a';
21         res[x]=BS(res[x],v[x].size(),x,cur+1);
22         if(res[x] == v[x].size())
23             return false;
24         cur=v[x][res[x]];
25     }
26     return true;
27 }

while()遍历:

二分查找:

慢了将近一秒是什么鬼,阔怕~~~~~~~~~~

同样的二分代码晚上提交超时又是什么鬼,增加数据了???

《论评测机的性能与时间的关系??》

猜你喜欢

转载自www.cnblogs.com/violet-acmer/p/10746691.html