Brutal force with LCS: this problem is easy if we can identify and transform the core matching algorithm it requires to LCS. Here two implementations of LCS are provided, one is through recursion the other is through explicitly maintaining a lookup table. For some reasons, the recursion solution time out on one system test.
usingnamespacestd;
// This will get TLE on one system test.. intlcs(conststring &s1, conststring &s2, int m, int n){ if (m == 0 || n == 0) return0; if ((s1[m - 1] == s2[n - 1]) && (m > 0 && n > 0)) return1 + lcs(s1, s2, m - 1, n - 1); else return max(lcs(s1, s2, m, n - 1), lcs(s1, s2, m - 1, n)); }
intlcs2(conststring &s1, conststring &s2, int m, int n){ vector<vector<int>> dp(m + 1, vector<int>(n + 1)); for (int i = 0; i <= m; ++i){ for (int j = 0; j <= n; ++j) { if (i == 0 || j == 0) dp[i][j] = 0; elseif (s1[i - 1] == s2[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1; else dp[i][j] = std::max(dp[i - 1][j], dp[i][j - 1]); } } return dp[m][n]; }
class RepeatStringEasy { public: intmaximalLength(string s){ if (s.empty()) return0; int ret = 0; for (int i = 0; i < s.size(); ++i) { string s1 = "", s2 = ""; for (int m = 0; m <= i; ++m) s1 += s[m]; for (int n = i + 1; n < s.size(); ++n) s2 += s[n]; ret = std::max(ret, 2 * lcs2(s1, s2, (int)s1.size(), (int)s2.size())); } return ret; } }
boolisRunaroundNumber(int n){ vector<int> num; unordered_map<int, int> map; while (n) { int d = n % 10; if (map.find(d) != map.end()) { returnfalse; } map[d] = 0; num.push_back(d); n /= 10; }
reverse(num.begin(), num.end()); int size = (int)num.size(), index = 0, next = -1; map[num[0]] = 1;
while (next != 0) { int next = (index + num[index]) % size; if (next == 0) { for (int i = 0; i < size; ++i) { if (map[num[i]] != 1) returnfalse; } returntrue; } if (map[num[next]] == 1) returnfalse; map[num[next]]++; index = next; } returnfalse; }
intmain(){ ifstream fin("runround.in"); ofstream fout("runround.out"); fin >> N; ++N; while (!isRunaroundNumber(N++)); fout << --N << endl; }
This solution however does not pass all tests, which has a time limit of 1 sec and a space limit of 16MB. The reason is the simple search will yield an exponential algorithm, given the state that we are about to explore is as much as 2^N, where N could be as large as 39. That said, it might be possible to optimize the search based algorithm using data structures that provides very optimized memory foot print with fast lookup, but I’ve not yet found such a data structure that satisfy the constraints.
Thinking from another perspective, the set / sum exhibits recursive nature and there are sub problems when solving each set partition, so dynamic programming is here for rescue: