#include <cstdio> #include <vector> using std::vector; const int kNotFound = -1; const int kBreakBruteForce = 50000000; int KMP(int *pattern, int *lps, int pattern_length, vector<int> *text, long text_length) { int j = 0; // index for pattern[] int i = 0; // index for text[] while (i < text_length) { if (pattern[j] == (*text)[i]) { j++; i++; } if (j == pattern_length) { // printf("Found pattern at index %d \n", i-j); return i - j; // j = lps[j-1]; } // mismatch after j matches else if (i < text_length && pattern[j] != (*text)[i]) { // Do not match lps[0..lps[j-1]] characters, // they will match anyway if (j != 0) j = lps[j-1]; else i = i+1; } } return kNotFound; } void LPS(int *pattern, int *lps, int pattern_length) { int len = 0; // length of the previous longest prefix suffix int i; lps[0] = 0; // lps[0] is always 0 i = 1; // the loop calculates lps[i] for i = 1 to M-1 while (i < pattern_length) { if (pattern[i] == pattern[len]) { len++; lps[i] = len; i++; } else { if (len != 0) { len = lps[len-1]; } else { lps[i] = 0; i++; } } } } int main() { int total_types, pattern_length; scanf("%d%d", &total_types, &pattern_length); int expansion_lengths[total_types]; vector<int> expansions[total_types]; for (int i = 0; i < total_types; ++i) { scanf("%d", &expansion_lengths[i]); for (int j = 0; j < expansion_lengths[i]; ++j) { int type; scanf("%d", &type); --type; expansions[i].push_back(type); } } int pattern[pattern_length]; int lps[pattern_length]; for (int i = 0; i < pattern_length; ++i) { scanf("%d", &pattern[i]); --pattern[i]; } LPS(pattern, lps, pattern_length); vector<int> *virus; vector<int> *oldVirus; oldVirus = new vector<int>(); virus = new vector<int>(); virus->push_back(0); int generation = 1; int global_length = 1; while (global_length < kBreakBruteForce) { int search_result = KMP(pattern, lps, pattern_length, virus, virus->size()); if (search_result != kNotFound) { printf("%d\n", generation); return 0; } vector<int> *tmp = oldVirus; oldVirus = virus; virus = tmp; for (int i = 0, j = 0; i < oldVirus->size(); ++i) { int old_cell = (*oldVirus)[i]; for (int k = 0; k < expansion_lengths[old_cell]; ++k) { int new_cell = expansions[old_cell][k]; if (j < virus->size()) { (*virus)[j] = new_cell; } else { virus->push_back(new_cell); } ++j; } } global_length += virus->size(); ++generation; } printf("-1\n"); return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | #include <cstdio> #include <vector> using std::vector; const int kNotFound = -1; const int kBreakBruteForce = 50000000; int KMP(int *pattern, int *lps, int pattern_length, vector<int> *text, long text_length) { int j = 0; // index for pattern[] int i = 0; // index for text[] while (i < text_length) { if (pattern[j] == (*text)[i]) { j++; i++; } if (j == pattern_length) { // printf("Found pattern at index %d \n", i-j); return i - j; // j = lps[j-1]; } // mismatch after j matches else if (i < text_length && pattern[j] != (*text)[i]) { // Do not match lps[0..lps[j-1]] characters, // they will match anyway if (j != 0) j = lps[j-1]; else i = i+1; } } return kNotFound; } void LPS(int *pattern, int *lps, int pattern_length) { int len = 0; // length of the previous longest prefix suffix int i; lps[0] = 0; // lps[0] is always 0 i = 1; // the loop calculates lps[i] for i = 1 to M-1 while (i < pattern_length) { if (pattern[i] == pattern[len]) { len++; lps[i] = len; i++; } else { if (len != 0) { len = lps[len-1]; } else { lps[i] = 0; i++; } } } } int main() { int total_types, pattern_length; scanf("%d%d", &total_types, &pattern_length); int expansion_lengths[total_types]; vector<int> expansions[total_types]; for (int i = 0; i < total_types; ++i) { scanf("%d", &expansion_lengths[i]); for (int j = 0; j < expansion_lengths[i]; ++j) { int type; scanf("%d", &type); --type; expansions[i].push_back(type); } } int pattern[pattern_length]; int lps[pattern_length]; for (int i = 0; i < pattern_length; ++i) { scanf("%d", &pattern[i]); --pattern[i]; } LPS(pattern, lps, pattern_length); vector<int> *virus; vector<int> *oldVirus; oldVirus = new vector<int>(); virus = new vector<int>(); virus->push_back(0); int generation = 1; int global_length = 1; while (global_length < kBreakBruteForce) { int search_result = KMP(pattern, lps, pattern_length, virus, virus->size()); if (search_result != kNotFound) { printf("%d\n", generation); return 0; } vector<int> *tmp = oldVirus; oldVirus = virus; virus = tmp; for (int i = 0, j = 0; i < oldVirus->size(); ++i) { int old_cell = (*oldVirus)[i]; for (int k = 0; k < expansion_lengths[old_cell]; ++k) { int new_cell = expansions[old_cell][k]; if (j < virus->size()) { (*virus)[j] = new_cell; } else { virus->push_back(new_cell); } ++j; } } global_length += virus->size(); ++generation; } printf("-1\n"); return 0; } |