bzoj 3507: [Cqoi2014]通配符匹配

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

dp一下,设$f_{i,j}$表示匹配到第$i$个通配符,第$j$个字符是否可行

分*和?来递推

有一个小姿势,就是在原串和匹配串后面都加一个?,好像挺有用的..

mdzz hash天天被卡..

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <algorithm>
 5 #define LL long long
 6 using namespace std;
 7 const LL Maxn = 100010;
 8 const LL Mod = 1e9+7;
 9 bool f[15][Maxn];
10 char s[Maxn], st[Maxn]; LL len, stl;
11 LL ps[Maxn], pst[Maxn], cf[Maxn];
12 LL hash ( LL *a, LL x, LL y ){
13     return (a[y]-(a[x-1]*cf[y-x+1])%Mod+Mod)%Mod;
14 }
15 LL pos[15], pl, n;
16 int main (){
17     LL i, j, k;
18     scanf ( "%s", s+1 );
19     len = strlen (s+1);
20     cf[1] = 26;
21     for ( i = 2; i <= 100000; i ++ ) cf[i] = (cf[i-1]*26)%Mod;
22     for ( i = 1; i <= len; i ++ ){
23         if ( s[i] >= ‘a‘ && s[i] <= ‘z‘ ) ps[i] = ((ps[i-1]*26)%Mod+s[i]-‘a‘)%Mod;
24         else {
25             ps[i] = (ps[i-1]*26)%Mod;
26             pos[++pl] = i;
27         }
28     }
29     ps[++len] = ‘?‘;
30     pos[++pl] = len;
31     scanf ( "%lld", &n );
32     while ( n -- ){
33         scanf ( "%s", st+1 );
34         stl = strlen (st+1);
35         for ( i = 1; i <= stl; i ++ ) pst[i] = ((pst[i-1]*26)%Mod+st[i]-‘a‘)%Mod;
36         st[++stl] = ‘?‘;
37         memset ( f, false, sizeof (f) );
38         f[0][0] = true;
39         for ( i = 1; i <= pl; i ++ ){
40             if ( s[pos[i]] == ‘*‘ ){
41                 for ( j = 1; j <= stl; j ++ ){
42                     if ( j-(pos[i]-pos[i-1]) < 0 ) continue;
43                     if ( f[i-1][j-(pos[i]-pos[i-1])] == true ){
44                         if ( pos[i] == pos[i-1]+1 ) break;
45                         else if ( hash ( ps, pos[i-1]+1, pos[i]-1 ) == hash ( pst, j-(pos[i]-pos[i-1])+1, j-1 ) ) break;
46                     }
47                 }
48                 for ( j = j-1; j <= stl; j ++ ) f[i][j] = true;
49             }
50             else {
51                 for ( j = 1; j <= stl; j ++ ){
52                     if ( j-(pos[i]-pos[i-1]) < 0 ) continue;
53                     if ( f[i-1][j-(pos[i]-pos[i-1])] == true ){
54                         if ( pos[i] == pos[i-1]+1 ) f[i][j] = true;
55                         else if ( hash ( ps, pos[i-1]+1, pos[i]-1 ) == hash ( pst, j-(pos[i]-pos[i-1])+1, j-1 ) ) f[i][j] = true;
56                     }
57                 }
58             }
59         }
60         if ( f[pl][stl] == true ) printf ( "YES\n" );
61         else printf ( "NO\n" );
62     }
63     return 0;
64 }

时间: 2024-08-07 01:31:10

bzoj 3507: [Cqoi2014]通配符匹配的相关文章

[bzoj3507 Cqoi2014]通配符匹配 (hash+DP)

传送门 Solution 显然用哈希233 设\(f[i][j]\)表示第i个通配符和当前第j个字符是否匹配 考虑两种通配符的特性,直接转移即可 Code #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #define F(i,a,b) for(register int i=(a);i<=(b);

L,uogu P3167 [CQOI2014]通配符匹配

Link 设\(f_{i,j}\)表示\(s\)从\(1\)到第\(i\)个通配符是否能匹配\(t_{1\sim j}\). 然后哈希一下再随便转移一下就好了. #include<cstdio> #include<cstring> using u64=unsigned long long; const int N=100007; u64 pw[N],hs[N],ht[N];char s[N],t[N];int f[12][N],pos[12]; int main() { int T

P3167 [CQOI2014]通配符匹配

吐槽 本来是去写AC自动机的,然后发现数据范围每个串100000,有100个串(???),连塞进trie树里都塞不进去,玩个鬼的AC自动机啊,tag不要乱打啊 最后拿字符串hash+爆搜一发搜过去了... 思路 挺恶心的搜索吧 考虑分段,按?号和*号分段,对于每段内的hash判断是否一致,*号和?号按题意处理即可 然后边界不要写挂就好了 代码 #include <cstdio> #include <cstring> #include <algorithm> using

bzoj3507【CQOI2014】通配符匹配

3507: [Cqoi2014]通配符匹配 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 309  Solved: 129 [Submit][Status][Discuss] Description 几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户.最常见的通配符有两个,一个 是星号(""'),可以匹配0个及以上的任意字符:另一个是问号("?"),可以匹配恰好一个任意字符. 现在需要你编写

【BZOJ-3507】通配符匹配 DP + Hash

3507: [Cqoi2014]通配符匹配 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 372  Solved: 156[Submit][Status][Discuss] Description 几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户.最常见的通配符有两个,一个是星号(“”’),可以匹配0个及以上的任意字符:另一个是问号(“?”),可以匹配恰好一个任意字符.现在需要你编写一个程序,对于给定的文件名列表和一个包

[BZOJ3507]通配符匹配

3507: [Cqoi2014]通配符匹配 Time Limit: 10 Sec  Memory Limit: 128 MB Description 几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户.最常见的通配符有两个,一个是星号(""'),可以匹配0个及以上的任意字符:另一个是问号("?"),可以匹配恰好一个任意字符.现在需要你编写一个程序,对于给定的文件名列表和一个包含通配符的字符串,判断哪些文件可以被匹配. Input 第一行是一个

WildcardMatching和Regex,通配符匹配和正则表达式匹配

WildcardMatching:通配符匹配 算法分析: 1. 二个指针i, j分别指向字符串.匹配公式. 2. 如果匹配,直接2个指针一起前进. 3. 如果匹配公式是*,在字符串中依次匹配即可. 注意记录上一次开始比较的位置 Implement wildcard pattern matching with support for '?' and '*' '?' Matches any single character. '*' Matches any sequence of character

[LeetCode] Wildcard Matching 通配符匹配

Implement wildcard pattern matching with support for '?' and '*'. '?' Matches any single character. '*' Matches any sequence of characters (including the empty sequence). The matching should cover the entire input string (not partial). The function p

LeetCode(44): 通配符匹配

Hard! 题目描述: 给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '*' 的通配符匹配. '?' 可以匹配任何单个字符. '*' 可以匹配任意字符串(包括空字符串). 两个字符串完全匹配才算匹配成功. 说明: s 可能为空,且只包含从 a-z 的小写字母. p 可能为空,且只包含从 a-z 的小写字母,以及字符 ? 和 *. 示例 1: 输入: s = "aa" p = "a" 输出: false 解释: "a"