传送门

M. Subsequence(思维)

题意

  给出一个只包含小写字母的字符串 $s$;

  接下来给你和 n 个 串 $t_{1,2,...,n}$,判断第 i 个串 $t_i$ 是否为 串 s 的子序列

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

•题解

  将 $s$ 中 26 个字母出现的位置分别记录下来;

  我放在了 vector<> 中;

 int n=strlen(s+);///个人习惯,s下标从1开始
for(int i=;i <= n;++i)
v[s[i]-'a'].push_back(i);

  假设当前要找的串 $t$ 长度为 m;

  那么,在匹配 $t_1$ 时,只需判断一下 $v[t_1 -\ 'a'].size()$ 是否大于 0 即可;

  如果 > 0 ,那么 $t_1$ 就匹配 $s$ 中的 $v[t_1 -\ 'a'][0]$ 位置;

  并定义 $pre=v[t_1 -\ 'a'][0]$,记录一下之前匹配好的位置;

  接下来匹配 $t_2$,类似 $t_1$ 的匹配;

  但是这次不仅要判断  $v[t_2 -\ 'a'].size()$ 是否大于 0,还需要找到 $v[t_2 -\ 'a']$ 是否存在 > pre 的值;

  因为 $t_2$ 在 $s$ 中匹配的位置势必要在 $t_1$ 之后,如果找到,更新 pre = $t_2$ 匹配的位置;

  然后,根据如上方式匹配 $t_2 , t_3 , \cdots , t_m$;

  存在匹配不成功的地方,就返回 false;

  我是将这个匹配方式放到了 Find() 函数里的;

  定义数组 a,$a_i$ 表示 $'a'+i$ 字符在 v 中匹配到的位置;

 bool Find()
{
int m=strlen(t+); mem(a,);
int pre=;
for(int i=;i <= m;++i)
{
int x=t[i]-'a';
///在v[x]中查找第一个 > pre 的位置
for(;a[x] < v[x].size() && v[x][a[x]] <= pre;a[x]++); ///匹配失败,返回false
if(a[x] == v[x].size())
return false;
///匹配成功,更新pre
pre=v[x][a[x]];
}
return true;
}

•Code

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

坑点

  起初,Find() 函数里,在 v[x] 中查找第一个 > pre 的位置时我用的方法是在 v[x] 中二分查找;

 auto it=upper_bound(v[x].begin(),v[x].end(),pre);

  每次判断 it 是否为 v[x].end();

  一直TLE可还行;

  

  这种题就是用来卡二分的么,可记住了;

•相似题(分割线:2019.6.21)

  类比Codeforces #565C 这道题,发现,这两道题有异曲同工之妙;

  首先,再分析一下本题的做法:

  在 s串中找 t串,如果找到,输出 "YES",反之,输出 "NO";

  如果将题意改为查找 s串 中最多有多少个 t串 呢?

  在类比一下Codeforces这道题,是不是发现两者的做法一样呢?

•Code

 #include<bits/stdc++.h>
using namespace std;
#define memF(a,b,n) for(int i=0;i <= n;a[i++]=b);
const int maxn=1e5+; char s[maxn];
char t[maxn];
int a[];
vector<int >p[];///存储字母在s中出现的位置 char *Solve()
{
memF(a,,); int len=strlen(t+);
int cur=;
for(int i=;i <= len;++i)
{
int index=t[i]-'a';
for(;a[index] < p[index].size() && p[index][a[index]] <= cur;a[index]++);
if(a[index] == p[index].size())
return "NO";
cur=p[index][a[index]];
}
return "YES";
}
void Init()
{
for(int i=;i < ;++i)
p[i].clear();
int len=strlen(s+);
for(int i=;i <= len;++i)
p[s[i]-'a'].push_back(i);
}
int main()
{
scanf("%s",s+);
Init(); int test;
scanf("%d",&test);
while(test--)
{
scanf("%s",t+);
puts(Solve());
}
return ;
}

2019南昌邀请赛网络预选赛 M. Subsequence的更多相关文章

  1. 2019南昌邀请赛网络预选赛 I. Max answer(单调栈+暴力??)

    传送门 题意: 给你你一序列 a,共 n 个元素,求最大的F(l,r): F(l,r) = (a[l]+a[l+1]+.....+a[r])*min(l,r); ([l,r]的区间和*区间最小值,F( ...

  2. 2019南昌邀请赛网络预选赛 J.Distance on the tree(树链剖分)

    传送门 题意: 给出一棵树,每条边都有权值: 给出 m 次询问,每次询问有三个参数 u,v,w ,求节点 u 与节点 v 之间权值 ≤ w 的路径个数: 题解: 昨天再打比赛的时候,中途,凯少和我说, ...

  3. POJ-2796 & 2019南昌邀请赛网络赛 I. 区间最大min*sum

    http://poj.org/problem?id=2796 https://nanti.jisuanke.com/t/38228 背景 给定一个序列,对于任意区间,min表示区间中最小的数,sum表 ...

  4. 2019南昌邀请赛网络赛:J distance on the tree

    1000ms 262144K   DSM(Data Structure Master) once learned about tree when he was preparing for NOIP(N ...

  5. [2019南昌邀请赛网络赛D][dp]

    https://nanti.jisuanke.com/t/38223 Xiao Ming recently indulges in match stick game and he thinks he ...

  6. 南昌邀请赛网络赛 D.Match Stick Game(dp)

    南昌邀请赛网络赛 D.Match Stick Game 题目传送门 题目就会给你一个长度为n的字符串,其中\(1<n<100\).这个字符串是一个表达式,只有加减运算符,然后输入的每一个字 ...

  7. 2019 ICPC南昌邀请赛网络赛比赛过程及题解

    解题过程 中午吃饭比较晚,到机房lfw开始发各队的账号密码,byf开始读D题,shl电脑卡的要死,启动中...然后听到谁说A题过了好多,然后shl让blf读A题,A题blf一下就A了.然后lfw读完M ...

  8. icpc 南昌邀请赛网络赛 Subsequence

    题目链接:https://nanti.jisuanke.com/t/38232 就是判断输入是不是子序列 没想到贡献了将近十几次罚时..........可以说是菜的真实了 用cin cout超时了 改 ...

  9. 2019 ICPC南昌邀请赛 网络赛 K. MORE XOR

    说明 \(\oplus x​\)为累异或 $ x^{\oplus(a)}​$为异或幂 题意&解法 题库链接 $ f(l,r)=\oplus_{i=l}^{r} a[i]$ $ g(l,r)=\ ...

随机推荐

  1. 使用cmd查看电脑连接过的wifi密码(二)

    上次写了一个查看wifi的bat文件(https://www.cnblogs.com/feiquan/p/9823402.html),发现有个问题就没法保存到记事本,而且还要处理不同的系统语言,这次重 ...

  2. javascript弹出模态窗体

    function openwindow(url,name,iWidth,iHeight){ //获得窗口的垂直位置 var iTop = (window.screen.availHeight-30-i ...

  3. win10 anaconda+tensorflow+keras

    最近想用python实现下lstm模型,然后看网上教程配置了下环境,中间出现了一些问题,记录下. 1.开始menu中anaconda文件夹下没有ipython的图标了. 我电脑里的anaconda是很 ...

  4. 如何制作中文Javadoc包,并导入到Eclipse

    原理:使用chm转换工具将chm文件转换为zip文件,导入eclipse中即可. 准备 JDK1.9 API 中文 谷歌翻译版:http://www.pc6.com/softview/SoftView ...

  5. R语言学习——向量

    以下为在RStudio中输入 #为注释符,其后内容程序不执行 > #向量是用于储存数值型.字符型或者逻辑型数据的一维数组.执行组合功能的函数c()可用来创建向量.示例如下: > a< ...

  6. (九)Delete an Index

    Now let’s delete the index that we just created and then list all the indexes again: 现在让我们删除刚刚创建的索引, ...

  7. 20175310 《Java程序设计》第9周学习总结

    20175310 <Java程序设计>第9周学习总结 本周博客:https://www.cnblogs.com/xicyannn/p/10785915.html 教材学习内容总结 这周学习 ...

  8. python之shutil

    ''' shutil 用来处理 文件 文件夹 压缩包 的模块 ''' import shutil # 拷贝文件内容 shutil.copyfileobj(open('old.xml', 'r'), o ...

  9. 在SQL Server中如何进行UPDATE TOP .....ORDER BY?

    前言 今天在导入数据到系统后需要根据时间排序对刚导入的TOP N条进行数据更新,之前没遇到过UPDATE TOP...ORDER BY,以此作为备忘录. SQL SERVER之UPDATE TOP.. ...

  10. Sublime 禁止自动升级

    打开SUblime   Prefreences  找到"设置-用户" 添加 "update_check":false, 即可禁用默认升级 此时完整如下 { &q ...