zoukankan      html  css  js  c++  java
  • [Cqoi2014]通配符匹配

    题意

    几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户。最常见的通配符有两个,一个是星号(“*”),可以匹配0个及以上的任意字符:另一个是问号(“?”),可以匹配恰好一个任意字符。

    现在需要你编写一个程序,对于给定的文件名列表和一个包含通配符的字符串,判断哪些文件可以被匹配。

    对于1 00%的数据,字符串长度不超过1 00000,1<=n<=100,通配符个数不超过10。

    分析

    参照DaD3zZ的题解。

    感觉复杂度有点玄学的做法。DP+Hash

    f[i][j]表示第i个通配符能否匹配到第j个位置。

    因为一个*会把字符串分成两段,所以这个*分开的两边一定是要求一样的,这里可以利用hash判断。然后我们就可以得到通配符串被*分成好几段,这样就可以得到转移。枚举起点,如果可以匹配就可以转移。

    有一些比较方便的处理,比如S最后加一个?,以及s最后加任意一个字符

    这样的时间复杂度封顶大概是O(N∗k∗len),这个转移其实时间复杂度是不满的,所以可以AC

    代码

    #include<bits/stdc++.h>
    #define rg register
    #define il inline
    #define co const
    template<class T>il T read()
    {
    	rg T data=0;
    	rg int w=1;
    	rg char ch=getchar();
    	while(!isdigit(ch))
    	{
    		if(ch=='-')
    			w=-1;
    		ch=getchar();
    	}
    	while(isdigit(ch))
    	{
    		data=data*10+ch-'0';
    		ch=getchar();
    	}
    	return data*w;
    }
    template<class T>il T read(rg T&x)
    {
    	return x=read<T>();
    }
    typedef unsigned long long ull;
    
    co int N=1e5+1,B=131;
    char S[N],s[N];
    ull hash[2][N],bin[N];
    int p[20],t;
    bool f[12][N];
    
    void Hashtable(char str[],int opt)
    {
    	int len=strlen(str+1);
    	for(int i=1;i<=len;++i)
    		hash[opt][i]=hash[opt][i-1]*B+str[i];
    }
    
    ull GetHash(int l,int r,int opt)
    {
    	return r>l?hash[opt][r]-hash[opt][l-1]*bin[r-l+1]:-1;
    }
    
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	bin[0]=1;
    	for(int i=1;i<N;++i)
    		bin[i]=bin[i-1]*B;
    	scanf("%s",S+1);
    	Hashtable(S,0);
    	int len=strlen(S+1);
    	for(int i=1;i<=len;++i)if(S[i]=='*'||S[i]=='?')
    		p[++t]=i;
    	p[++t]=++len,S[len]='?';
    	int n=read<int>();
    	while(n--)
    	{
    		scanf("%s",s+1);
    		Hashtable(s,1);
    		memset(f,0,sizeof f);f[0][0]=1;
    		int len=strlen(s+1);s[++len]='@';
    		for(int i=0;i<=t-1;++i)
    		{
    			if(S[p[i]]=='*')
    				for(int j=1;j<=len;++j)
    					f[i][j]|=f[i][j-1];
    			for(int j=0;j<=len;++j)
    				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))
    				{
    					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;
    				}
    		}
    		puts(f[t][len]?"YES":"NO");
    	}
    	return 0;
    }
    
  • 相关阅读:
    eclipse中在线添加TestNG插件步骤(需联网)
    [IOI2008] Type Printer 打印机
    P2765 魔术球问题
    [HNOI2004]敲砖块
    P3931 SAC E#1
    [WC2005]友好的生物
    P1357 花园
    [SDOI2016]征途
    [APIO2014]序列分割
    [HNOI2008]玩具装箱TOY
  • 原文地址:https://www.cnblogs.com/autoint/p/10328652.html
Copyright © 2011-2022 走看看