• 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
    " );
    61         else printf ( "NO
    " ); 
    62     }
    63     return 0;
    64 }
    View Code
  • 相关阅读:
    Socket
    字符串,byte,字典转换整理
    1-嵌入式面试题库
    10-FreeRTOS 队列
    9-FreeRTOS API获取任务使用CPU时间
    7-代码区 | 常量区 | 静态区(全局区) | 堆区 | 栈区
    8-FreeRTOS任务API
    7-FreeRTOS时间片进行任务调度
    6-C指针
    用Union体测试处理器大小端
  • 原文地址:https://www.cnblogs.com/darklove/p/6022440.html
Copyright © 2020-2023  润新知