zoukankan      html  css  js  c++  java
  • bzoj 3507 DP+哈希

    [Cqoi2014]通配符匹配

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 541  Solved: 235
    [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

    DP+哈希

    f[i][j]表示第i个通配符和第j个字符能否匹配,然后搞搞转移,注意两种通配符的区别。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<algorithm>
     6 using namespace std;
     7 #define ULL unsigned long long
     8 #define MAXN 100010
     9 #define BASE 131
    10 char S[MAXN],s[MAXN];
    11 ULL hash[2][MAXN],bin[MAXN];
    12 int p[20],t,N;
    13 bool f[12][MAXN];
    14 inline void Hashtable(char str[],int opt)
    15 {
    16     int len=strlen(str+1);
    17     for (int i=1; i<=len; i++) hash[opt][i]=hash[opt][i-1]*BASE+str[i];
    18 }
    19 inline ULL GetHash(int l,int r,int opt)
    20 {
    21     return r>l? hash[opt][r]-hash[opt][l-1]*bin[r-l+1] : -1;
    22 }
    23 int main()
    24 {
    25     bin[0]=1; for (int i=1; i<=MAXN-1; i++) bin[i]=bin[i-1]*BASE;
    26     scanf("%s",S+1); Hashtable(S,0);
    27     int len=strlen(S+1);
    28     for (int i=1; i<=len; i++) if (S[i]=='*' || S[i]=='?') p[++t]=i;
    29     p[++t]=++len; S[len]='?';
    30     scanf("%d",&N);
    31     while (N--)
    32         {
    33             scanf("%s",s+1); Hashtable(s,1);
    34             memset(f,0,sizeof(f)); f[0][0]=1;
    35             int len=strlen(s+1); s[++len]='@';
    36             for (int i=0; i<=t-1; i++)
    37                 {
    38                     if (S[p[i]]=='*') for (int j=1; j<=len; j++) if (f[i][j-1]) f[i][j]=1;
    39                     for (int j=0; j<=len; j++)
    40                         if (f[i][j] && GetHash(j+1,j+(p[i+1]-1)-(p[i]+1)+1,1)==GetHash(p[i]+1,p[i+1]-1,0))
    41                             if (S[p[i+1]]=='?') f[i+1][j+(p[i+1]-1)-(p[i]+1)+1+1]=1; else f[i+1][j+(p[i+1]-1)-(p[i]+1)+1]=1;
    42                 }
    43             if (f[t][len]) puts("YES"); else puts("NO");
    44         }
    45     return 0;
    46 }
  • 相关阅读:
    [leetcode]Combination SumII
    NSum小结
    image 与 canvas 的相互转化
    $_SERVER 相关变量
    最近做的项目,总结一下。
    开始在博客园,写博客,先写点东西。
    Codeforces Round #584 C. Paint the Digits
    Codeforces Round #584 B. Koala and Lights
    Codeforces Round #584 A. Paint the Numbers
    HDU-2296-Ring(AC自动机, DP)
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8530839.html
Copyright © 2011-2022 走看看