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;}