ZOJ 3494 BCD Code (AC自动机+数位DP,5级)
来源:互联网 发布:数据字典 javaweb 编辑:程序博客网 时间:2024/04/30 13:40
Binary-coded decimal (BCD) is an encoding for decimal numbers in which each digit is represented by its own binary sequence. To encode a decimal number using the common BCD encoding, each decimal digit is stored in a 4-bit nibble:
Decimal: 0 1 2 3 4 5 6 7 8 9BCD: 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001
Thus, the BCD encoding for the number 127 would be:
0001 0010 0111
We are going to transfer all the integers from A to B, both inclusive, with BCD codes. But we find that some continuous bits, named forbidden code, may lead to errors. If the encoding of some integer contains these forbidden codes, the integer can not be transferred correctly. Now we need your help to calculate how many integers can be transferred correctly.
Input
There are multiple test cases. The first line of input is an integer T ≈ 100 indicating the number of test cases.
The first line of each test case contains one integer N, the number of forbidden codes ( 0 ≤N ≤ 100). Then N lines follow, each of which contains a 0-1 string whose length is no more than 20. The next line contains two positive integersA and B. Neither A or B contains leading zeros and 0 <A ≤ B < 10200.
Output
For each test case, output the number of integers between A and B whose codes do not contain any of theN forbidden codes in their BCD codes. For the result may be very large, you just need to output itmod 1000000009.
Sample Input
31001 101001 100111111 100
Sample Output
3998
References
- http://en.wikipedia.org/wiki/Binary-coded_decimal
Author: GUAN, Yao
思路:先用AC自动机记录fobiden 的BCD码,然后预处理出10进制的BCD转移态,
然后一个简单的数位DP就搞定了。
#include<iostream>#include<cstring>#include<cstdio>#include<queue>#define FOR(i,a,b) for(int i=a;i<=b;++i)#define clr(f,z) memset(f,z,sizeof(f))#define LL long longusing namespace std;const int mm=2013;const int MOD=1000000009;class AC{public://f 失败指针 int ch[mm][2],f[mm]; bool val[mm]; int sz; AC() { sz=1;clr(ch[0],0);val[0]=0; } void clear() { sz=1;clr(ch[0],0);val[0]=0; } int idx(char x) { return x-'0'; } void insert(char*s) { int u=0,c; for(int i=0;s[i];++i) { c=idx(s[i]); if(!ch[u][c])//add a node { val[sz]=0; clr(ch[sz],0);ch[u][c]=sz++; } u=ch[u][c]; } val[u]=1; } void getFail() { int u=0,v,r; queue<int>Q; f[0]=0; FOR(i,0,1) if(ch[0][i])Q.push(ch[0][i]),f[ ch[0][i] ]=0; while(!Q.empty()) { r=Q.front();Q.pop(); val[r]|=val[ f[r] ];//其子集符合即可 FOR(c,0,1) { u=ch[r][c]; if(!u){ ch[r][c]=ch[ f[r] ][c]; continue;} Q.push(u); v=f[r]; while(v&&!ch[v][c])v=f[v];//从父节点找存在的FAIl f[u]=ch[v][c]; } } } int bcd[mm][10]; int chage(int fa,int num) { if(val[fa])return -1; int cur=fa; for(int i=3;i>=0;--i) { if(val[ ch[cur][(num>>i)&1] ])return -1; cur=ch[cur][ (num>>i)&1 ]; } return cur; } void get_BCD()///从某节点开始的转移态 { FOR(i,0,sz-1) FOR(j,0,9) bcd[i][j]=chage(i,j); } void BCD_out() { FOR(i,0,sz-1) FOR(j,0,9) printf("bcd=%d %d %d \n",i,j,bcd[i][j]); } LL dp[210][mm];int bit[210],pos; LL DP(int pp,int s,bool big,bool nozero) { if(pp == 0)return 1; if(big&&dp[pp][s]!=-1)return dp[pp][s]; LL ans = 0; if(nozero) { if(bcd[s][0]!=-1)ans += DP(pp-1,bcd[s][0],big || bit[pp]!=0,nozero); ans %= MOD; } else { ans += DP(pp-1,s,big || bit[pp]!=0,nozero); ans %= MOD; } int kn= big?9:bit[pp]; for(int i = 1;i<=kn;i++) { if(bcd[s][i]!=-1) { ans += DP(pp-1,bcd[s][i],big||i!=kn,1); ans %=MOD; } } if(big&&nozero)dp[pp][s] = ans;///important big is not mean nozero return ans; } LL get(char*s) { clr(dp,-1); pos=0; int len=strlen(s); for(int i=len-1;i>=0;--i) bit[++pos]=s[i]-'0'; //return dfs(pos,0,1,1); return DP(pos,0,0,0); }}ac;char s[222];int main(){ int cas,n; while(~scanf("%d",&cas)) { FOR(ca,1,cas) { ac.clear(); scanf("%d",&n); FOR(i,1,n) { scanf("%s",s); ac.insert(s); } ac.getFail(); ac.get_BCD(); //ac.BCD_out(); LL ans=0; scanf("%s",s); int len=strlen(s); for(int i=len-1;i>=0;--i) if(s[i]>'0'){--s[i];break;} else s[i]='9'; //cout<<s<<endl; ans-=ac.get(s); scanf("%s",s); ans+=ac.get(s); ans%=MOD; if(ans<0)ans+=MOD; printf("%lld\n",ans); } }}
- ZOJ 3494 BCD Code (AC自动机+数位DP,5级)
- ZOJ 3494 BCD Code(AC自动机+数位DP)
- ZOJ 3494 BCD Code 数位DP+AC自动机
- 【MZ】ZOJ 3494 BCD Code AC自动机+数位DP
- ZOJ 3494 BCD Code(AC自动机+数位DP)
- ZOJ 3494 BCD Code(AC自动机+数位DP)
- ZOJ 3494 BCD Code AC自动机+数位DP
- ZOJ 3494 BCD Code AC自动机+数位DP
- 【ZOJ】3494 BCD Code AC自动机+数位DP
- zoj 3494 BCD Code AC自动机+数位dp
- zoj 3494 BCD Code(AC自动机+数位dp)
- ZOJ 3494 BCD Code AC自动机 + 数位DP
- 【AC自动机+数位DP】【zoj 3494】BCD Code
- ZOJ Problem Set - 3494 BCD Code AC自动机+数位DP
- zoj 3494 BCD Code (ac自动机+数位dp)
- [AC自动机+数位dp] zoj 3494 BCD Code
- ZOJ - 3494 BCD Code(AC自动机+数位DP)
- ZOJ 3494 BCD Code (AC自动机 + 数位DP)
- 搬家啦,CSDN我来了,博客园再见啦
- 【整数操作】02.递归公式的非递归做法
- 老码农教你学英语
- 产品经理必读的10篇文章
- Win7下要求以管理员权限运行程序
- ZOJ 3494 BCD Code (AC自动机+数位DP,5级)
- poj 3321
- SPOJ Equation :求 1/n!=1/x+1/y 的解的个数
- CPU时间片
- codility上的问题 (22)Phi 2012
- 转载:PostgreSQL分区表(Table Partitioning)应用
- 青春代码,微电
- Qt安装—搭建VS2008+QT开发环境
- Help a PhD candidate out!解题报告