生活随笔
收集整理的這篇文章主要介紹了
bzoj3507: [Cqoi2014]通配符匹配
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
這題一眼看上去像是KMP。。。莫名旁邊的zzz說是ACMachine,而且是真的有dalao用這個做。。。
然后呢經(jīng)過%羊神的題解呢,發(fā)現(xiàn)居然是DP+hash字符串比較,但是時間復雜度就很差了(rank倒數(shù)第3,還是無法慢過羊神,果然是神一樣的男人),不過又學到了有用的東西。
具體hash就是看作一個x進制的數(shù),然后求值取mod(rp不好那也沒辦法了),然后觀察到通配符很小,f[i][j]就是表示枚舉到第i通配符,枚舉到b串第j個位置,可不可以匹配。
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
const int mod=
1000000007;
LL cf[110000];char sa[
110000],sb[
110000];
int pos[
110000],plen;LL ha[110000],hb[
110000];
LL HASH(LL *h,
int x,
int y)
{return (h[y]-(h[x-
1]*cf[y-x+
1])%mod+mod)%
mod;
}bool f[
20][
110000];
int main()
{cf[1]=
31;
for(
int i=
2;i<=
100000;i++)cf[i]=(cf[i-
1]*
31)%
mod;scanf("%s",sa+
1);
int alen=strlen(sa+
1);sa[++alen]=
'?';ha[0]=
0;plen=
0;for(
int i=
1;i<=alen;i++
)if(sa[i]>=
'a'&&sa[i]<=
'z')ha[i]=((ha[i-
1]*
31)%mod+(sa[i]-
'a'+
1))%
mod;elseha[i]=((ha[i-
1]*
31)%mod+
27)%mod, pos[++plen]=
i;int n;scanf("%d",&
n);while(n--
){scanf("%s",sb+
1);
int blen=strlen(sb+
1);sb[++blen]=
'?';hb[0]=
0;for(
int i=
1;i<=blen;i++
)hb[i]=((hb[i-
1]*
31)%mod+(sb[i]-
'a'+
1))%
mod;memset(f,false,
sizeof(f));f[
0][
0]=
true;for(
int i=
1;i<=plen;i++
){int pl=pos[i-
1]+
1,pr=pos[i]-
1;int L=pr-pl+
1;if(sa[pos[i]]==
'*'){for(
int j=L+
1;j<=blen;j++
){int l=(j-L+
1)-
1,r=j-
1;if(f[i-
1][l-
1]==
true)if(pos[i]==pos[i-
1]+
1||HASH(ha,pl,pr)==
HASH(hb,l,r)){for(
int k=j-
1;k<=blen;k++)f[i][k]=
true;break;}}}else{for(
int j=L+
1;j<=blen;j++
){int l=(j-L+
1)-
1,r=j-
1;if(f[i-
1][l-
1]==
true)if(pos[i]==pos[i-
1]+
1||HASH(ha,pl,pr)==HASH(hb,l,r))f[i][j]=
true;}}}if(f[plen][blen]==
true)printf(
"YES\n");else printf(
"NO\n");}return 0;
}
轉(zhuǎn)載于:https://www.cnblogs.com/AKCqhzdy/p/7787830.html
總結(jié)
以上是生活随笔為你收集整理的bzoj3507: [Cqoi2014]通配符匹配的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。