24 июля в 20:00 MSD состоится 4й раунд TopCoder Open
№ | Пользователь | Рейтинг |
---|---|---|
1 | tourist | 3985 |
2 | jiangly | 3814 |
3 | jqdai0815 | 3682 |
4 | Benq | 3529 |
5 | orzdevinwang | 3526 |
6 | ksun48 | 3517 |
7 | Radewoosh | 3410 |
8 | hos.lyric | 3399 |
9 | ecnerwala | 3392 |
9 | Um_nik | 3392 |
Страны | Города | Организации | Всё → |
№ | Пользователь | Вклад |
---|---|---|
1 | cry | 169 |
2 | maomao90 | 162 |
2 | Um_nik | 162 |
4 | atcoder_official | 161 |
5 | djm03178 | 158 |
6 | -is-this-fft- | 157 |
7 | adamant | 155 |
8 | awoo | 154 |
8 | Dominater069 | 154 |
10 | luogu_official | 150 |
Название |
---|
Кто как её делал? Моя гипотеза заключалась в том, что если у нас есть ненулевое произведение цифр x, то список кандидатов для него состоит из чисел вида n = ???..??99..9****, где p(n) = x, ??..?? - наименьшее число в классе чисел с таким произведением цифр.
1) случаи когда все элементы prod - нули. Тогда ответ равен:
10 если prod.size() == 1
100 если prod.size() < 12
1000 в противном случае
2) в противном случае находим какой-то ненулевой элемент prod и генерим его разложения на сомножители (упорядоченные по возрастанию) от 1 до 9 длиной до 19 включительно. Далее неплохо бы поперебирать порядок. Но будет долго. Можно добавить такой несложный хак. Будем перебирать цифры числа начиная с младшей. Если в какой-то момент мы поймем, что все перестановки оставшихся цифр будут давать такие X, которые будут генерить один и тот же вектор prod, перестаем перебирать все перестановки, вместо этого выписываем оставшиеся цифры в порядке возрастания. Другими словами если у нас prod.size() == 8, мы хотим сгенерить разложение 0-го числа из цифр 1, 2, 3 и на последнюю позицию мы выбрали число 1, то независимо от того как мы расставим оставшиеся числа, переполнения не произойдет, потому как 1 + 8 < 10. То есть самое лучшее число в этом случае 231. Такой хак достаточен для того чтобы решение проходило. Именно в нем я и набажил.
- проверим что числа правильно заканчиваются: очевидно что при данном M, i-е число заканчивается на (M+i) % 10. Поэтому все произведения цифр prod[i] должны делиться на (M+i) % 10 или быть равны нулю если (M+i) % 10 == 0. Если это не выполняется, то данное M нам не подходит
- проверим что числа правильно начинаются: в рамках одного (M+i) / 10, т. е. пока у нас нет очередного переноса в старшие разряды, все произведения цифр исключая младшую prod[i] / [(M+i) % 10] должны быть равны (иначе не выполнится уловие что все prod[] идут по порядку). Если это не выполняется, то данное M нам также не подходит
- когда нашли подходящую младшую цифру M - откусываеем ее, перестраиваем prod, считаем рекурсивно ответ через меньшую подзадачу как 10 * rec(prod_new) + M, и минимизируем
Работает это видимо очень быстро - полходящих цифр очень мало, а количество элементов в prod убывает примерно в 10 раз на каждом шаге.