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 }
作者:Ra1nbow
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。