AC自动机+DP
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <queue> #include <algorithm> #include <vector> #include <cstring> #include <stack> #include <cctype> #include <utility> #include <map> #include <string> #include <climits> #include <set> #include <string> #include <sstream> #include <utility> #include <ctime> using std::priority_queue; using std::vector; using std::swap; using std::stack; using std::sort; using std::max; using std::min; using std::pair; using std::map; using std::string; using std::cin; using std::cout; using std::set; using std::queue; using std::string; using std::istringstream; using std::make_pair; using std::getline; using std::greater; using std::endl; using std::multimap; typedef long long LL; typedef unsigned long long ULL; typedef pair<int, int> PAIR; typedef multimap<int, int> MMAP; const int MAXN(1111); const int SIGMA_SIZE(4); const int MAXM(110); const int MAXE(4000010); const int MAXH(18); const int INFI((INT_MAX-1) >> 2); const int BASE(131); const int MOD(20090717); const ULL LIM(1000000000000000ull); map<char, int> mp; struct AC { int ch[MAXN][SIGMA_SIZE]; bool val[MAXN]; int f[MAXN]; int size; void init() { memset(ch[0], 0, sizeof(ch[0])); f[0] = val[0] = 0; size = 1; } inline int idx(char temp) { return mp[temp]; } void insert(char *S) { int u = 0, id; for(; *S; ++S) { id = idx(*S); if(!ch[u][id]) { memset(ch[size], 0, sizeof(ch[size])); val[size] = 0; ch[u][id] = size++; } u = ch[u][id]; } val[u] = true; } int que[MAXN]; int front, back; void construct() { front = back = 0; int cur, u; for(int i = 0; i < SIGMA_SIZE; ++i) { u = ch[0][i]; if(u) { que[back++] = u; f[u] = 0; } } while(front < back) { cur = que[front++]; for(int i = 0; i < SIGMA_SIZE; ++i) { u = ch[cur][i]; if(u) { que[back++] = u; f[u] = ch[f[cur]][i]; val[u] |= val[f[u]]; } else ch[cur][i] = ch[f[cur]][i]; } } } }; AC ac; char str[1010]; int table[2][MAXN]; void solve(int len) { int cur = 0, last = 1; memset(table[last], -1, sizeof(table[last])); table[last][0] = 0; for(int i = 0; i < len; ++i) { memset(table[cur], -1, sizeof(table[cur])); for(int j = 0; j < ac.size; ++j) if(table[last][j] >= 0) { int tv = table[last][j], ts; for(int k = 0; k < SIGMA_SIZE; ++k) if(!ac.val[ts = ac.ch[j][k]]) { if(table[cur][ts] == -1) table[cur][ts] = tv+(k == mp[str[i]]? 0: 1); else table[cur][ts] = min(table[cur][ts], tv+(k == mp[str[i]]? 0: 1)); } } cur ^= 1; last ^= 1; } int ans = INFI; for(int i = 0; i < ac.size; ++i) if(table[last][i] != -1) ans = min(ans, table[last][i]); printf("%d\n", ans == INFI? -1: ans); } int main() { mp.insert(make_pair('A', 0)); mp.insert(make_pair('G', 1)); mp.insert(make_pair('C', 2)); mp.insert(make_pair('T', 3)); int n, n_case(0); while(scanf("%d", &n), n) { ac.init(); for(int i = 0; i < n; ++i) { scanf("%s", str); ac.insert(str); } ac.construct(); scanf("%s", str); printf("Case %d: ", ++n_case); solve(strlen(str)); } return 0; }