1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 #define MAXN 1010 6 #define INF 123456789 7 using namespace std; 8 struct Trie { 9 int fail, next[4]; 10 bool end; 11 void Init() { 12 end = false; 13 fail = 0; 14 memset(next, 0, sizeof(next)); 15 } 16 }; 17 Trie tree[MAXN]; 18 int size, dp[MAXN][MAXN]; 19 char str[MAXN]; 20 inline int GET(char ch) { 21 if (ch == 'A') 22 return 0; 23 if (ch == 'C') 24 return 1; 25 if (ch == 'G') 26 return 2; 27 return 3; 28 } 29 void Insert(char *s) { 30 int now, t; 31 for (now = 0; *s; s++) { 32 t = GET(*s); 33 if (!tree[now].next[t]) { 34 tree[++size].Init(); 35 tree[now].next[t] = size; 36 } 37 now = tree[now].next[t]; 38 } 39 tree[now].end = true; 40 } 41 void BFS() { 42 int now, i, p; 43 queue<int> q; 44 q.push(0); 45 while (!q.empty()) { 46 now = q.front(); 47 q.pop(); 48 for (i = 0; i < 4; i++) { 49 if (tree[now].next[i]) { 50 p = tree[now].next[i]; 51 q.push(p); 52 if (now) 53 tree[p].fail = tree[tree[now].fail].next[i]; 54 tree[p].end |= tree[tree[p].fail].end; 55 } else 56 tree[now].next[i] = tree[tree[now].fail].next[i]; 57 } 58 } 59 } 60 void DoIt() { 61 int ans, i, j, k, p, t, n; 62 n = strlen(str + 1); 63 for (i = 0; i <= n; i++) { 64 for (j = 0; j <= size; j++) 65 dp[i][j] = INF; 66 } 67 dp[0][0] = 0; 68 for (i = 1; i <= n; i++) { 69 t = GET(str[i]); 70 for (j = 0; j <= size; j++) { 71 if (tree[j].end || dp[i - 1][j] >= INF) 72 continue; 73 for (k = 0; k < 4; k++) { 74 p = tree[j].next[k]; 75 if (tree[p].end) 76 continue; 77 dp[i][p] = min(dp[i][p], dp[i - 1][j] + (k != t)); 78 } 79 } 80 } 81 for (ans = INF,i = 0; i <= size; i++) 82 ans = min(ans, dp[n][i]); 83 if (ans < INF) 84 printf("%d\n", ans); 85 else 86 puts("-1"); 87 } 88 int main() { 89 int n, ca = 1; 90 while (scanf("%d", &n), n) { 91 tree[0].Init(); 92 for (size = 0; n--;) { 93 scanf(" %s", str); 94 Insert(str); 95 } 96 BFS(); 97 scanf(" %s", str + 1); 98 printf("Case %d: ", ca++); 99 DoIt(); 100 } 101 return 0; 102 }