P3167 [CQOI2014]通配符匹配

吐槽

本来是去写AC自动机的,然后发现数据范围每个串100000,有100个串(???),连塞进trie树里都塞不进去,玩个鬼的AC自动机啊,tag不要乱打啊
最后拿字符串hash+爆搜一发搜过去了。。。

思路

挺恶心的搜索吧
考虑分段,按?号和*号分段,对于每段内的hash判断是否一致,*号和?号按题意处理即可
然后边界不要写挂就好了

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int base=131;
int xing[100100],wen[100100],n,lens,cntx,cntw,lent;
unsigned long long hashs1[100100],hashs2[100100],pow[100100];
char s[100100],t[100100];
void init(void){
    pow[0]=1;
    for(int i=1;i<=100001;i++)
        pow[i]=pow[i-1]*base;
}
unsigned long long hash1(int l,int r){
    return hashs1[r]-hashs1[l-1]*pow[r-l+1];
}
unsigned long long hash2(int l,int r){
    return hashs2[r]-hashs2[l-1]*pow[r-l+1];
}
bool dfs(int poss,int post){
    // printf("%d %d\n",poss,post);
    if(poss==lens+1&&post==lent+1){
        return true;
    }
    else if(poss==lens+1||post==lent+1)
        return false;
    if(s[poss]=='*'){
        for(int i=post;i<=lent+1;i++)
            if(dfs(poss+1,i))
                return true;
        return false;
    }
    else if(s[poss]=='?'){
        return dfs(poss+1,post+1);
    }
    else{
        int tx=lower_bound(xing+1,xing+cntx+1,poss)-(xing),tw=lower_bound(wen+1,wen+cntw+1,poss)-(wen);
        // printf("tx=%d tw=%d\n",tx,tw);
        // printf("compare 1(%d,%d) 2(%d,%d) :\n",poss,min(xing[tx],wen[tw])-1,post,post+min(xing[tx],wen[tw])-poss-1);
        if(hash1(poss,min(xing[tx],wen[tw])-1)==hash2(post,post+(min(xing[tx],wen[tw])-poss-1))){
            // printf("true\n");
            return dfs(min(xing[tx],wen[tw]),post+(min(xing[tx],wen[tw])-poss));
        }
        else
        {
            // printf("false\n");
            return false;
        }
    }
}
int main(){
    init();
    scanf("%s",s+1);
    lens=strlen(s+1);
    for(int i=1;i<=lens;i++){
        if(s[i]!='*'||s[i]!='?')
            hashs1[i]=hashs1[i-1]*base+s[i];
        if(s[i]=='*')
            xing[++cntx]=i;
        if(s[i]=='?')
            wen[++cntw]=i;
    }
    xing[++cntx]=lens+1;
    wen[++cntw]=lens+1;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%s",t+1);
        lent=strlen(t+1);
        memset(hashs2,0,sizeof(hashs2));
        for(int j=1;j<=lent;j++){
            hashs2[j]=hashs2[j-1]*base+t[j];
        }
        printf("%s\n",dfs(1,1)?"YES":"NO");
    }
    return 0;
}

原文地址:https://www.cnblogs.com/dreagonm/p/10456403.html

时间: 2024-11-17 16:36:02

P3167 [CQOI2014]通配符匹配的相关文章

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

bzoj 3507: [Cqoi2014]通配符匹配

Description 几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户.最常见的通配符有两个,一个是星号(“”’),可以匹配0个及以上的任意字符:另一个是问号(“?”),可以匹配恰好一个任意字符.现在需要你编写一个程序,对于给定的文件名列表和一个包含通配符的字符串,判断哪些文件可以被匹配. Input 第一行是一个由小写字母和上述通配符组成的字符串.第二行包含一个整数n,表示文件个数.接下来n行,每行为一个仅包含小写字母字符串,表示文件名列表. Output 输出n行

[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);

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"