Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 06.08.2024, 12:40
Аспирант
Отправить личное сообщение для Himmelin Посмотреть профиль Найти все сообщения от Himmelin
 
Регистрация: 14.01.2019
Сообщений: 31

Решение задачи
Число называется счастливым, если его цифры расположены в неубывающем порядке и сумма цифр равна num. Количество цифр указано в параметре k. Необходимо найти все счастливые числа в диапазоне k (например: если k = 3, диапазон от 100 до 999). Ответ нужно дать в виде массива, который содержит количество счастливых чисел, первое и последнее счастливое число. В случае, если счастливые числа не найдены, возвращается массив с единственным элементом 0.

Примеры: luckyNumbers(10, 3) выведет [8, 118, 334];
luckyNumbers(27, 3) выведет [1, 999, 999].

Если кто-то с такой задачей сталкивался, подскажите, как решать.

Последний раз редактировалось Himmelin, 07.08.2024 в 09:29.
Ответить с цитированием
  #2 (permalink)  
Старый 07.08.2024, 20:55
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,012

function getCount(n, k) {
    if (k < 1) return 0;
    const map = new Map();

    function calc(f, n, k) {
        if (n < f * k || n > 9 * k) {
            return 0;
        }
        if (k < 2) {
            return 1;
        }
        const key = `${f}_${n}_${k}`;
        const saved = map.get(key);
        if (saved != null) { return saved; }

        let count = 0;

        for (let i = f; i <= 9; ++i) {
            count += calc(i, n - i, k - 1);
        }

        map.set(key, count);

        return count;
    }

    return calc(1, n, k);
}

function getMin(n, k) {
    if (k < 1 || n < k || n > 9 * k) {
        return 0;
    }
    let r = 0;
    while (k > 1 && n - 1 <= 9 * (k - 1)) {
        r = r * 10 + 1;
        n--;
        k--;
    }
    k--;
    r = r * 10 + n - 9 * k;
    while (k > 0) {
        r = r * 10 + 9;
        k--;
    }
    return r;
}

function getMax(n, k) {
    if (k < 1 || n < k || n > 9 * k) {
        return 0;
    }
    const base = Math.floor(n / k);
    const head = k - n % k;
    let r = 0;
    for (i = 0; i < k; ++i) {
        r = r * 10 + base + (i < head ? 0 : 1);
    }
    return r;
}

function luckyNumbers(n, k) {
    const max = getMax(n, k);
    if (!max) return [0];

    return [getCount(n, k), getMin(n, k), max];
}

alert(luckyNumbers(10, 3));
Ответить с цитированием
  #3 (permalink)  
Старый 08.08.2024, 12:36
Аспирант
Отправить личное сообщение для Himmelin Посмотреть профиль Найти все сообщения от Himmelin
 
Регистрация: 14.01.2019
Сообщений: 31

Спасибо большое!
Ответить с цитированием
  #4 (permalink)  
Старый 09.08.2024, 15:29
Аспирант
Отправить личное сообщение для Himmelin Посмотреть профиль Найти все сообщения от Himmelin
 
Регистрация: 14.01.2019
Сообщений: 31

Можно уточнить, как вы пришли к такому решению? Какая-то формула математическая есть? Потому что я детально изучил решение и понял, что сам бы не смог придумать такие формулы.
Ответить с цитированием
  #5 (permalink)  
Старый 09.08.2024, 15:59
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,012

Да никакой особой формулы нет. Простые наблюдения. Максимальное число всегда будет иметь вид ААА...АВВВ...В, где В = А+1, потому что стремимся увеличить старшие разряды (которые слева). Аналогично, минимальное 111...1А999...9, здесь уменьшаем старшие разряды. Ты и сам можешь поэкспериментировать с числами и заметить это.

Для подсчета количества не требуется бежать циклом от минимального числа к максимальному и каждое проверять на соответствие условиям. Суммируем количества вариантов для всех значений старшего разряда. Если старший разряд равен f, то за ним стоит calc(f, n - f, k - 1) вариантов - потому что справа от него (k - 1) цифр, сумма которых равна (n - f), а в старшем разряде цифра не менее чем f. Ну и оптимизация в виде Map, потому что по факту будет много повторных расчетов, и ускорение от оптимизации весьма ощутимое.
Ответить с цитированием
  #6 (permalink)  
Старый 10.08.2024, 12:20
Аспирант
Отправить личное сообщение для Himmelin Посмотреть профиль Найти все сообщения от Himmelin
 
Регистрация: 14.01.2019
Сообщений: 31

Думаю стоит попробовать да с числами поиграться. Вот я как раз циклом пытался перебирать и очень много времени у меня это занимало, когда разрядов > 10 вообще помирал интерпретатор Моя проблема в том, что я мыслю только циклами и массивами в подобных задачах, надо пробовать по-другому думать начинать.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Объект с функциями. Решение задачи. Gm5 Общие вопросы Javascript 3 09.11.2021 10:29
Подскажите с чего начать решение задачи prototip Общие вопросы Javascript 1 13.07.2021 14:33
решение задачи / JavaScript Jhon Общие вопросы Javascript 1 30.05.2014 17:15
Решение задачи, с использованием цикла for. Eldon Общие вопросы Javascript 4 19.11.2012 10:41
Решение задачи с объектом math biz87 Общие вопросы Javascript 4 26.08.2011 13:50