#define debug_printf(fmt, ...) //#define debug_printf(fmt, ...) do { printf(fmt, __VA_ARGS__); } while (0) #include <cstdio> #include <cstdlib> #include <cstring> #include <climits> #include <cassert> #include <vector> #include <set> #include <map> #include <deque> #include <algorithm> #include <functional> #include <random> #include <limits> #include <iostream> const long long LLMAX = (std::numeric_limits<long long>()).max(); const long long LLMIN = (std::numeric_limits<long long>()).min(); const int N_max = 500; const int M_max = 1000; const int Sum_li_max = 1000; int H[N_max + 1 /*1-based*/][Sum_li_max]; int H_len[N_max + 1 /*1-based*/]; const int Time_max = 65000; std::vector<int> S[Time_max]; struct HinS { HinS(int h, int offset) { this->h = h; this->offset = offset; } int h; int offset; }; std::vector<std::vector<HinS> > hinss[Time_max]; int N; int earliest = INT_MAX; void prepare_build_and_try(const int time); void build_and_try(const int time, const int s); void prepare_build_and_try(const int time) { if (earliest <= time) { return; } for (int t=0; t < time; ++t) { if (S[t].size() == S[time].size()) { bool mismatch = false; for (int s=0; s < (int) S[time].size(); ++s) { if (S[t][s] != S[time][s]) { mismatch = true; break; } } if (!mismatch) { return; } } } if (S[time].size() == 1 && S[time][0] == 1) { earliest = time; return; } debug_printf("%d\n", time); hinss[time].clear(); for (int i=0; i < (int) S[time].size(); ++i) { hinss[time].push_back(std::vector<HinS>()); } for (int i=1; i <= N; ++i) { int* Hi = H[i]; int Hi_len = H_len[i]; // Find all occurrences of Hi suffixes that S starts with. for (int o=-Hi_len+1; o < 0; ++o) { bool mismatch = false; for (int s=0; s < (int) S[time].size() && s - o < Hi_len; ++s) { if (S[time][s] != Hi[s - o]) { mismatch = true; break; } } if (!mismatch) { hinss[time][0].push_back(HinS(i, o)); } } // Find all occurrences of Hi inside S; also include all Hi prefixes that S ends with. for (int s=0; s < (int) S[time].size(); ++s) { bool mismatch = false; for (int h=0; h < Hi_len && s + h < (int) S[time].size(); ++h) { if (S[time][s + h] != Hi[h]) { mismatch = true; break; } } if (!mismatch) { hinss[time][s].push_back(HinS(i, 0)); } } } build_and_try(time, 0); } void build_and_try(const int time, const int s) { if (time + 1 == Time_max) { return; } if (s >= (int) S[time].size()) { prepare_build_and_try(time + 1); } else { for (int i=0; i < (int) hinss[time][s].size(); ++i) { HinS& hins = hinss[time][s][i]; S[time + 1].push_back(hins.h); build_and_try(time, s + H_len[hins.h] + hins.offset); S[time + 1].pop_back(); } } } int main() { std::ios_base::sync_with_stdio(false); int M; scanf("%d %d", &N, &M); for (int i=0; i < N; ++i) { int li; scanf("%d", &li); H_len[i + 1] = li; for (int j=0; j < li; ++j) { int hij; scanf("%d", &hij); H[i + 1][j] = hij; } } for (int i=0; i < M; ++i) { int si; scanf("%d", &si); S[0].push_back(si); } prepare_build_and_try(0); printf("%d\n", (earliest != INT_MAX) ? earliest + 1 : -1); }
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 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | #define debug_printf(fmt, ...) //#define debug_printf(fmt, ...) do { printf(fmt, __VA_ARGS__); } while (0) #include <cstdio> #include <cstdlib> #include <cstring> #include <climits> #include <cassert> #include <vector> #include <set> #include <map> #include <deque> #include <algorithm> #include <functional> #include <random> #include <limits> #include <iostream> const long long LLMAX = (std::numeric_limits<long long>()).max(); const long long LLMIN = (std::numeric_limits<long long>()).min(); const int N_max = 500; const int M_max = 1000; const int Sum_li_max = 1000; int H[N_max + 1 /*1-based*/][Sum_li_max]; int H_len[N_max + 1 /*1-based*/]; const int Time_max = 65000; std::vector<int> S[Time_max]; struct HinS { HinS(int h, int offset) { this->h = h; this->offset = offset; } int h; int offset; }; std::vector<std::vector<HinS> > hinss[Time_max]; int N; int earliest = INT_MAX; void prepare_build_and_try(const int time); void build_and_try(const int time, const int s); void prepare_build_and_try(const int time) { if (earliest <= time) { return; } for (int t=0; t < time; ++t) { if (S[t].size() == S[time].size()) { bool mismatch = false; for (int s=0; s < (int) S[time].size(); ++s) { if (S[t][s] != S[time][s]) { mismatch = true; break; } } if (!mismatch) { return; } } } if (S[time].size() == 1 && S[time][0] == 1) { earliest = time; return; } debug_printf("%d\n", time); hinss[time].clear(); for (int i=0; i < (int) S[time].size(); ++i) { hinss[time].push_back(std::vector<HinS>()); } for (int i=1; i <= N; ++i) { int* Hi = H[i]; int Hi_len = H_len[i]; // Find all occurrences of Hi suffixes that S starts with. for (int o=-Hi_len+1; o < 0; ++o) { bool mismatch = false; for (int s=0; s < (int) S[time].size() && s - o < Hi_len; ++s) { if (S[time][s] != Hi[s - o]) { mismatch = true; break; } } if (!mismatch) { hinss[time][0].push_back(HinS(i, o)); } } // Find all occurrences of Hi inside S; also include all Hi prefixes that S ends with. for (int s=0; s < (int) S[time].size(); ++s) { bool mismatch = false; for (int h=0; h < Hi_len && s + h < (int) S[time].size(); ++h) { if (S[time][s + h] != Hi[h]) { mismatch = true; break; } } if (!mismatch) { hinss[time][s].push_back(HinS(i, 0)); } } } build_and_try(time, 0); } void build_and_try(const int time, const int s) { if (time + 1 == Time_max) { return; } if (s >= (int) S[time].size()) { prepare_build_and_try(time + 1); } else { for (int i=0; i < (int) hinss[time][s].size(); ++i) { HinS& hins = hinss[time][s][i]; S[time + 1].push_back(hins.h); build_and_try(time, s + H_len[hins.h] + hins.offset); S[time + 1].pop_back(); } } } int main() { std::ios_base::sync_with_stdio(false); int M; scanf("%d %d", &N, &M); for (int i=0; i < N; ++i) { int li; scanf("%d", &li); H_len[i + 1] = li; for (int j=0; j < li; ++j) { int hij; scanf("%d", &hij); H[i + 1][j] = hij; } } for (int i=0; i < M; ++i) { int si; scanf("%d", &si); S[0].push_back(si); } prepare_build_and_try(0); printf("%d\n", (earliest != INT_MAX) ? earliest + 1 : -1); } |