3507: [Cqoi2014]通配符匹配

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 372  Solved: 156
[Submit][Status][Discuss]

Description

几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户。最常见的通配符有两个,一个是星号(“”’),可以匹配0个及以上的任意字符:另一个是问号(“?”),可以匹配恰好一个任意字符。
现在需要你编写一个程序,对于给定的文件名列表和一个包含通配符的字符串,判断哪些文件可以被匹配。

Input

第一行是一个由小写字母和上述通配符组成的字符串。
第二行包含一个整数n,表示文件个数。
接下来n行,每行为一个仅包含小写字母字符串,表示文件名列表。

Output

输出n行,每行为“YES”或“NO”,表示对应文件能否被通配符匹配。

Sample Input

*aca?ctc
6
acaacatctc
acatctc
aacacatctc
aggggcaacacctc
aggggcaacatctc
aggggcaacctct

Sample Output

YES
YES
YES
YES
YES
NO

HINT

对于1 00%的数据
  ·字符串长度不超过1 00000
  ·  1 <=n<=100
  ·通配符个数不超过10

Source

Solution

感觉复杂度有点玄学的做法。
DP+Hash
f[i][j]表示第i个通配符能否匹配到第j个位置。
因为一个*会把字符串分成两段,所以这个*分开的两边一定是要求一样的,这里可以利用hash判断。
然后我们就可以得到通配符串被*分成好几段,这样就可以得到转移。
枚举起点,如果可以匹配就可以转移。
有一些比较方便的处理,比如S最后加一个?,以及s最后加任意一个字符

这样的时间复杂度封顶大概是$O(N*k*len)$,所以一开始自己想到了但是没敢写,但是发现这个转移其实时间复杂度是不满的,所以可以AC

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define ULL unsigned long long
#define MAXN 100010
#define BASE 131
char S[MAXN],s[MAXN];
ULL hash[][MAXN],bin[MAXN];
int p[],t,N;
bool f[][MAXN];
inline void Hashtable(char str[],int opt)
{
int len=strlen(str+);
for (int i=; i<=len; i++) hash[opt][i]=hash[opt][i-]*BASE+str[i];
}
inline ULL GetHash(int l,int r,int opt)
{
return r>l? hash[opt][r]-hash[opt][l-]*bin[r-l+] : -;
}
int main()
{
bin[]=; for (int i=; i<=MAXN-; i++) bin[i]=bin[i-]*BASE;
scanf("%s",S+); Hashtable(S,);
int len=strlen(S+);
for (int i=; i<=len; i++) if (S[i]=='*' || S[i]=='?') p[++t]=i;
p[++t]=++len; S[len]='?';
// for (int i=1; i<=t; i++) printf("%d %c\n",p[i],S[p[i]]);
scanf("%d",&N);
while (N--)
{
scanf("%s",s+); Hashtable(s,);
memset(f,,sizeof(f)); f[][]=;
int len=strlen(s+); s[++len]='@';
for (int i=; i<=t-; i++)
{
if (S[p[i]]=='*') for (int j=; j<=len; j++) if (f[i][j-]) f[i][j]=;
for (int j=; j<=len; j++)
if (f[i][j] && GetHash(j+,j+(p[i+]-)-(p[i]+)+,)==GetHash(p[i]+,p[i+]-,))
if (S[p[i+]]=='?') f[i+][j+(p[i+]-)-(p[i]+)++]=; else f[i+][j+(p[i+]-)-(p[i]+)+]=;
}
if (f[t][len]) puts("YES"); else puts("NO");
}
return ;
}

【BZOJ-3507】通配符匹配 DP + Hash的更多相关文章

  1. BZOJ 3507 通配符匹配(贪心+hash或贪心+AC自动机)

    首先可以对n个目标串单独进行处理. 对于每个目标串,考虑把模式串按'*'进行划分为cnt段.首尾两段一定得于原串进行匹配.剩下的cnt-2段尽量与最靠左的起点进行匹配. 对于剩下的cnt-2段.每段又 ...

  2. [BZOJ3507][CQOI2014]通配符匹配(DP+Hash)

    显然f[i][j]表示S匹配到第i个通配符,T匹配到第j个字符,是否可行. 一次一起转移两个通配符之间的所有字符,Hash判断. 稍微有点细节.常数极大卡时过排名倒数,可能是没自然溢出的原因. #in ...

  3. [CQOI2014][bzoj3507] 通配符匹配 [字符串hash+dp]

    题面 传送门 思路 0x01 KMP 一个非常显然而优秀的想法:把模板串按照'*'分段,然后对于每一段求$next$,'?'就当成可以对于任意字符匹配就行了 对于每个文本串,从前往后找第一个可以匹配的 ...

  4. BZOJ 1264 基因匹配(DP+线段树)

    很有意思的一道题啊. 求两个序列的最大公共子序列.保证每个序列中含有1-n各5个. 如果直接LCS显然是TLE的.该题与普通的LCS不同的是每个序列中含有1-n各5个. 考虑LCS的经典DP方程.dp ...

  5. bzoj 3507: [Cqoi2014]通配符匹配

    Description 几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户.最常见的通配符有两个,一个是星号(“”’),可以匹配0个及以上的任意字符:另一个是问号(“?”),可 ...

  6. bzoj 3507 DP+哈希

    [Cqoi2014]通配符匹配 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 541  Solved: 235[Submit][Status][Dis ...

  7. 【BZOJ3507】通配符匹配(哈希,动态规划)

    [BZOJ3507]通配符匹配(哈希,动态规划) 题面 BZOJ 题解 对于匹配唯一存在影响的只有通配符,而\(?\)的影响也并不大,所以唯一需要仔细考虑的是\(*\). 考虑一个\(dp\),设\( ...

  8. [BZOJ3507]通配符匹配

    3507: [Cqoi2014]通配符匹配 Time Limit: 10 Sec  Memory Limit: 128 MB Description 几乎所有操作系统的命令行界面(CLI)中都支持文件 ...

  9. BZOJ3507 [Cqoi2014]通配符匹配

    题意 几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户.最常见的通配符有两个,一个是星号("*"),可以匹配0个及以上的任意字符:另一个是问号(" ...

随机推荐

  1. 关于安卓APP的启动界面

    刚学安卓App开发的朋友们,可能会遇到一个问题,就是人家的App刚进入会有一个页面出现一会儿后消失,   这个页面可以用来打广告,也可以声明App的主题,所以说这个启动页面至关重要,接下来,我把我的代 ...

  2. databtables 设置(显示)行号

    var table = $('#priceStrategtyTable').DataTable({         "rowCallback": function( row, da ...

  3. [Java编程思想-学习笔记]第1章 对象导论

    1.1  抽象过程 Java是一门面向对象的语言,它的一个优点在于只针对待解问题抽象,而不用为具体的计算机结构而烦心,这使得Java有完美的移植性,也即Java的口号"Write Once, ...

  4. CentOS 7 恢复 Windows 启动项

    安装Linux时一般会自动识别windows系统并添加引导项,而 CentOS 默认不支持 NTFS 分区,CentOS7采用了Grub2,与CentOS6有区别.手动引导windows分区修改配置稍 ...

  5. JQuery日历控件

    日历控件最后一弹——JQuery实现,换汤不换药.原理一模一样,换了种实现工具.关于日历的终于写完了,接下来研究研究nodejs.嗯,近期就这点事了. 同样还是将input的id设置成calendar ...

  6. Acionbar logo

    问题: 在使用Actionbar时,默认在左上角是会有一个跟软件发布时的LOGO一样的图标,在大多数情况下按照默认图标进行显示已经很好,既使得软件整体统一,也方便省事.但有些情况下,还是希望不同的界面 ...

  7. 每天一个linux命令(1):ls命令

    1. 命令格式: ls [选项] [目录名] 2. 命令功能: 列出目标目录中所有的子目录和文件. 4. 常用范例: 例一:列出/home/peidachang文件夹下的所有文件和目录的详细资料 命令 ...

  8. Java:类与继承

    Java:类与继承 对于面向对象的程序设计语言来说,类毫无疑问是其最重要的基础.抽象.封装.继承.多态这四大特性都离不开类,只有存在类,才能体现面向对象编程的特点,今天我们就来了解一些类与继承的相关知 ...

  9. OpenStack 企业私有云的若干需求(3):多租户和租户间隔离(multi-tenancy and isolation)

    本系列会介绍OpenStack 企业私有云的几个需求: 自动扩展(Auto-scaling)支持 多租户和租户隔离 (multi-tenancy and tenancy isolation) 混合云( ...

  10. [原]那些年整理的Linux常用命令,简单明了

    查询相关 find 按规则查找某个文件或文件夹,包括子目录 find . -name '*.sh' -- 以.sh结尾的文件 find . -name '*channel*' -- 包含channel ...