Gym
来源:互联网 发布:android系统源码架构 编辑:程序博客网 时间:2024/05/17 23:28
Problem E Passwords
It's that time of the year again when you go back to work and
need to choose new passwords for all your services. The rulesenforced by the system administrators are very strict, and the
password you choose must obey the following restrictions:
· It must contain only letters and digits.
·It must have between A and B characters (inclusive).
·It must have at least one lowercase letter, one uppercase letter and one digit.
·It cannot contain any word of a collection of forbidden words (the blacklist).
A word of the blacklist is considered to be contained in the password if it appears as a substring,
that is, if it occurs as a consecutive sequence of characters (regardless of it being upper or
lower case). For instance, swerc is a substring of SwErC, 2016swerc2016 or SWERC16, but it
is not a substring of ICPC or sw16erc.
Additionally, for the purposes of avoiding the blacklist, you cannot use l33t. Specically,
some digits can be interpreted as letters, namely the 0 ('o'), 1 ('i'), 3 ('e'), 5 ('s') and 7 ('t').
This implies that for example 5w3rC would be an occurrence of swerc, and that abcL337def
contains the word leet.
You cannot stop thinking about all these rules and you wonder how many dierent valid
passwords there are... Can you calculate how many passwords would obey these rules?
Task
Given a blacklist with N words and two integers A and B, your task is to compute the numberof dierent valid passwords that exist following the given constraints: made up of only letters
and digits; length between A and B (inclusive); at least one lowercase letter, one uppercase
letter, and one digit; no blacklisted substring. Since this number can be very big, compute it
modulo 1 000 003.
Input
The rst line contains two integers, A and B, specifying respectively the minimum andmaximum length of the password. The second line contains an integer N, the number of
words of the blacklist. The following N lines each contains a string Wi indicating a word in
the blacklist. These words are formed only by lowercase letters.
Constraints
3 A B 20 Size of the password0 N 50 Number of words in the blacklist
1 length(Wi) 20 Size of each blacklist word
Output
The output should contain a single line with an integer indicating the number of validpasswords modulo 1 000 003. A valid password is one that respects all of the given constraints.
Sample Input
3 59
swerc
icpc
fbi
cia
bio
z
hi
no
yes
Sample Output
607886Sample Explanation
In this case there are exactly 378 609 020 valid passwords and378 609 020 mod 1 000 003 = 607 886 :
Some examples of valid passwords are: aA1, B23tT, 1g9K or B2j.
Some examples of invalid passwords are: aaA (it does not contain digits), 12a (it does not
contain upper case letters), a12A34 (length > 5) or bB10 (contains bio as substring).
Source
SWERC'2016 Universidade do PortoGym - 101174E
My Solution
题意:给出n个由小写字母模式串,用大写字母、小写字母、十进制数字构造的长度为[A, B]的字符串,
且满足一下限制条件:1、必须有至少一个大写字母至少一个小写字母和一个数字。
2、不包含任一模式串(不区分大小写)。
3、对于o、i、e、s、t,在模式串时和0、1、3、5、7不区分。
求构造出的满足条件的字符串种数。
AC自动机+额外的限制条件+状态压缩dp
首先这题的原始版本是 给出n模式串,构造不含任一模式串的长度为m的字符串种类数 http://blog.csdn.net/prolightsfxjh/article/details/54729646。
然后这题添加1、用大小写+数字进行构造+不区分大小写。
2、 构造出的字符串有至少一个大写字母至少一个小写字母和一个数字。
3、对于o、i、e、s、t,在模式串时和0、1、3、5、7不区分。
对于第二个条件,可以直接添加一维dp[8] 来状态压缩。
对于第一个条件则转移的时候直接转移2次即可,//mod( dp[ac.ch[j][k]][i][w | 1] += dp[j][i-1][w] ); mod( dp[ac.ch[j][k]][i][w | 2] += dp[j][i-1][w] );
对于第三个条件则如果是o、i、e、s、t 则在不是危险节点的时候额外转移一次,//mod( dp[ac.ch[j][k]][i][w | 4] += dp[j][i-1][w] );
其它数字则不管当前节点是否为危险节点都进行转移。
答案就是 sigma{dp[0 ~ ac.sz][[A, B]]}
复杂度 O(max(A, B) * len* n * 8 * CHAR_SIZE) == 4.16e6
#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <map>using namespace std;typedef long long LL;const int CHAR_SIZE = 26;const int MAX_SIZE = 1e3 + 8;const int MOD = 1000003;inline int mp(char ch){ return ch - 'a';}struct AC_Machine{ int ch[MAX_SIZE][CHAR_SIZE], danger[MAX_SIZE], fail[MAX_SIZE]; int sz; void init(){ sz = 1; memset(ch[0], 0, sizeof ch[0]); memset(danger, 0, sizeof danger); } void _insert(char *s){ int n = strlen(s); int u = 0, c; for(int i = 0; i < n; i++){ c = mp(s[i]); if(!ch[u][c]){ memset(ch[sz], 0, sizeof ch[sz]); danger[sz] = 0; ch[u][c] = sz++; } u = ch[u][c]; } danger[u] = 1; } void _build(){ queue<int> Q; fail[0] = 0; for(int c = 0, u; c < CHAR_SIZE; c++){ u = ch[0][c]; if(u){Q.push(u); fail[u] = 0;} } int r; while(!Q.empty()){ r = Q.front(); Q.pop(); danger[r] |= danger[fail[r]]; for(int c = 0, u; c < CHAR_SIZE; c++){ u = ch[r][c]; if(!u){ch[r][c] = ch[fail[r]][c]; continue; } fail[u] = ch[fail[r]][c]; Q.push(u); } } }}ac;char s[22];inline void mod(int &x){ x -= x / MOD * MOD;}int dp[MAX_SIZE][22][8];int main(){ #ifdef LOCAL freopen("e.txt", "r", stdin); //freopen("e.out", "w", stdout); int T = 1; while(T--){ #endif // LOCAL //ios::sync_with_stdio(false); cin.tie(0); int n, m, p; // n - > A, m -> B scanf("%d%d%d", &n, &m, &p); ac.init(); while(p--){ scanf("%s", s); ac._insert(s); } int i, j, k, w; memset(dp, 0, sizeof dp); ac._build(); dp[0][0][0] = 1; for(i = 1; i <= m; i++){ for(j = 0; j < ac.sz; j++){ for(w = 0; w < 8; w++){ if(dp[j][i-1][w] == 0) continue; for(k = 0; k < CHAR_SIZE; k++){ if(!ac.danger[ac.ch[j][k]]){ mod( dp[ac.ch[j][k]][i][w | 1] += dp[j][i-1][w] ); mod( dp[ac.ch[j][k]][i][w | 2] += dp[j][i-1][w] ); if(k == 'o' - 'a' || k == 'i' - 'a' || k == 'e' - 'a' || k == 's' - 'a' || k == 't' - 'a'){ mod( dp[ac.ch[j][k]][i][w | 4] += dp[j][i-1][w] ); // 0 1 3 5 7 } } } mod( dp[0][i][w | 4] += dp[j][i-1][w] ); // 9 for(k = 1; k < 10; k++){// 2 4 6 8 if(!(k&1)) mod( dp[0][i][w | 4] += dp[j][i-1][w] ); } } } } int ans = 0; for(j = n; j <= m; j++){ for(i = 0; i < ac.sz; i++){ mod( ans += dp[i][j][8-1]); } } printf("%d\n", ans); #ifdef LOCAL cout << endl; } #endif // LOCAL return 0;}
Thank you!
------from ProLights
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- 那一年, 我第一次在工作中用到了三次握手的分析
- 【一步一步】Spring 源码环境搭建
- java工程师基础知识面试
- * 24种设计模式——责任链模式
- 设置meta标签 清除页面缓存,如:<meta http-equiv="Cache-Control" content="no-cache"/>
- Gym
- 在Visual Studio中使用DLL-项目引用链接lib
- bootstrap注册界面
- 2017/7/19小程序基础类库更新,Map组件又可以在微信开发者工具中使用了
- JAVA中的反射机制
- 十七天
- HDU-4089 Activation(概率DP)
- 【LeetCode】 刷题 Add Two Numbers
- 为什么6的反码 11111001是-7