|
| 1 | +--- |
| 2 | +id: cf-100886G |
| 3 | +source: CF |
| 4 | +title: Maximum Product |
| 5 | +author: Daniel Zhu |
| 6 | +--- |
| 7 | + |
| 8 | +<Spoiler title="Hint"> |
| 9 | + |
| 10 | +If $l = 1$, what will the best solution always be? |
| 11 | + |
| 12 | +</Spoiler> |
| 13 | + |
| 14 | +## Explanation |
| 15 | + |
| 16 | +### $l = 1$ |
| 17 | + |
| 18 | +Let's start with an example: $l = 1$ and $r = 875$. Observe that we really need to consider three numbers as viable answers: $875$, $799$, and $869$. Try to think about why, and how this generalizes! |
| 19 | + |
| 20 | +### $l \neq 1$ |
| 21 | + |
| 22 | +We can apply a very similar approach when $l \neq 1$. In fact, it's almost identical, with one minor difference. Consider the case where $l = 855$ and $r = 875$, just as before. The only difference is we can no longer consider $799$ as a viable answer, as it is less than $l$. Again, try to think about how to generalize this! |
| 23 | + |
| 24 | +## Implementation |
| 25 | + |
| 26 | +**Time Complexity:** $\mathcal{O}(D^2)$, where $D$ is the maximum number of digits (19). |
| 27 | + |
| 28 | +<LanguageSection> |
| 29 | +<CPPSection> |
| 30 | + |
| 31 | +```cpp |
| 32 | +#include <bits/stdc++.h> |
| 33 | +using ll = long long; |
| 34 | +using namespace std; |
| 35 | + |
| 36 | +/** @return the product of the given string's digits (-1 if empty) */ |
| 37 | +ll prod(string s) { |
| 38 | + if (!s.length()) { return -1; } |
| 39 | + ll res = 1; |
| 40 | + for (char c : s) { res *= c - '0'; } |
| 41 | + return res; |
| 42 | +} |
| 43 | + |
| 44 | +int main() { |
| 45 | + string l, r; |
| 46 | + cin >> l >> r; |
| 47 | + |
| 48 | + // pad beginning of l with zeros |
| 49 | + // l = 12, r = 132 -> l = 012, r = 132 |
| 50 | + while (l.length() < r.length()) { l.insert(l.begin(), '0'); } |
| 51 | + string ans = ""; |
| 52 | + |
| 53 | + // i -> length of LCP (longest common prefix) of str and r |
| 54 | + bool eq = true; // whether l[0, i) = r[0, i) |
| 55 | + for (int i = 0; i <= r.length(); i++) { |
| 56 | + string cur = r.substr(0, i); |
| 57 | + eq = eq && l[i] == r[i]; |
| 58 | + /* |
| 59 | + * in this case, str[i] must equal r[i] |
| 60 | + * and now the shared prefix has length i + 1 |
| 61 | + * which contradicts our assumption that the LCP has length i |
| 62 | + */ |
| 63 | + if (i < r.length() && eq) { continue; } |
| 64 | + if (i < r.length()) { cur += char(r[i] - 1); } |
| 65 | + // fill remaining digits with 9's |
| 66 | + cur += string(r.length() - cur.length(), '9'); |
| 67 | + if (prod(cur) > prod(ans)) { ans = cur; } |
| 68 | + } |
| 69 | + |
| 70 | + // remove any leading zeros from ans |
| 71 | + while (ans[0] == '0') { ans.erase(ans.begin()); } |
| 72 | + cout << ans << endl; |
| 73 | +} |
| 74 | +``` |
| 75 | +
|
| 76 | +</CPPSection> |
| 77 | +</LanguageSection> |
0 commit comments