Рубрики

Наименьшее кратное из N, сформированное с использованием заданного набора цифр

Для заданного набора цифр S и целого числа N задача состоит в том, чтобы найти наименьшее положительное целое число, если оно существует, которое содержит только цифры из S и кратно N. Обратите внимание, что цифры из набора могут быть использованы несколько раз.

Примеры:

Input: S[] = {5, 2, 3}, N = 12
Output: 252
We can observe that 252 is formed using {2, 5} and is a multiple of 12

Input: S[] = {1, 3, 5, 7, 9}, N = 2
Output: -1
Multiple of 2 would always be an even number but from the given set of digits even number can’t be formed.

Простой подход состоит в том, чтобы отсортировать набор цифр и затем перейти от наименьшего к наибольшему числу, сформированному с использованием заданных цифр. Мы проверяем каждое число, удовлетворяет ли оно заданному условию. Реализация этого способа привела бы к экспоненциальной временной сложности.

Лучше всего использовать модульную арифметику. Итак, мы поддерживаем очередь, в которой мы будем хранить модуль чисел, сформированный с использованием набора цифр с заданным числом N. Первоначально в очереди было бы (однозначное число)% N, но мы можем вычислить (двузначное число)% N, используя,

New_mod = (Old_mod * 10 + digit) % N

Используя вышеприведенное выражение, мы можем вычислить значения модуля из нескольких цифр. Это приложение динамического программирования, так как мы строим наше решение от меньшего состояния к большему состоянию. Мы поддерживаем другой вектор, чтобы гарантировать, что элемент для вставки в очередь уже присутствует в очереди или нет. Он использует хеширование для обеспечения O (1) временной сложности. Мы использовали другой вектор пары, который также использует хеширование для хранения значений, и его структура

result[new_mod] = { current_element_of_queue, digit}

Этот вектор будет использоваться для построения решения:

  1. Сортировать набор цифр.
  2. Инициализируйте два вектора dp и result с INT_MAX и {-1, 0} соответственно.
  3. Инициализируйте очередь и вставьте цифру% N.
  4. Делай пока очередь не пустая.
  5. Удалите переднее значение из очереди и для каждой цифры в наборе найдите (сформированное число)% N, используя написанное выше выражение.
  6. Если мы не получили 0 в качестве значения модуля до того, как очередь пуста, то наименьшего положительного числа не существует, иначе отследим вектор результата от 0-го индекса, пока мы не получим -1 для любого индекса.
  7. Поместите все эти значения в другой вектор и переверните его.
  8. Это наше необходимое решение.

Ниже приведена реализация вышеуказанного подхода:

C ++

// C ++ реализация подхода
#include <bits/stdc++.h>

using namespace std;

  
// Функция для возврата нужного номера

int findSmallestNumber(vector<int>& arr, int n)

{

  

    // Инициализируем оба вектора с их начальными значениями

    vector<int> dp(n, numeric_limits<int>::max() - 5);

    vector<pair<int, int> > result(n, make_pair(-1, 0));

  

    // Сортируем вектор цифр

    sort(arr.begin(), arr.end());

  

    // Инициализируем очередь

    queue<int> q;

    for (auto i : arr) {

        if (i != 0) {

  

            // Если значение модуля отсутствует

            // в очереди

            if (dp[i % n] > 1e9) {

  

                // Вычисляем модуль цифр заданного числа и

                // обновляем очередь и векторы

                q.push(i % n);

                dp[i % n] = 1;

                result[i % n] = { -1, i };

            }

        }

    }

  

    // Пока очередь не пуста

    while (!q.empty()) {

  

        // Удалить первый элемент очереди

        int u = q.front();

        q.pop();

        for (auto i : arr) {

  

            // Вычисляем новые значения модуля, используя старую очередь

            // значения и каждая цифра множества

            int v = (u * 10 + i) % n;

  

            // если значение отсутствует в очереди

            if (dp[u] + 1 < dp[v]) {

                dp[v] = dp[u] + 1;

                q.push(v);

                result[v] = { u, i };

            }

        }

    }

  

    // Если требуемое условие не может быть выполнено

    if (dp[0] > 1e9)

        return -1;

    else {

  

        // Инициализируем новый вектор

        vector<int> ans;

        int u = 0;

        while (u != -1) {

  

            // Построение решения путем возврата

            ans.push_back(result[u].second);

            u = result[u].first;

        }

  

        // Обратный вектор

        reverse(ans.begin(), ans.end());

        for (auto i : ans) {

  

            // Возвращаем нужный номер

            return i;

        }

    }

}

  
// Код драйвера

int main()

{

    vector<int> arr = { 5, 2, 3 };

    int n = 12;

  

    cout << findSmallestNumber(arr, n);

  

    return 0;

}

python3

# Python3 реализация подхода

  
# Функция для возврата нужного номера

def findSmallestNumber(arr, n): 

   

    # Инициализировать оба вектора с их начальными значениями

    dp = [float('inf')] *

    result = [(-1, 0)] *

  

    # Сортировать вектор цифр

    arr.sort() 

  

    # Инициализировать очередь

    q = [] 

    for i in arr:  

        if i != 0:  

  

            # Если значение модуля не

            # присутствует в очереди

            if dp[i % n] > 10 ** 9:  

  

                # Вычислить модуль чисел заданного числа

                # и обновить очередь и векторы

                q.append(i % n) 

                dp[i % n] = 1 

                result[i % n] = -1, i  

               

    # Пока очередь не пуста

    while len(q) > 0:

  

        # Удалить первый элемент из очереди

        u = q.pop(0

        for i in arr:  

  

            # Вычислить новые значения модуля, используя старые

            # значения очереди и каждая цифра множества

            v = (u * 10 + i) %

  

            # Если значение отсутствует в очереди

            if dp[u] + 1 < dp[v]:  

                dp[v] = dp[u] + 1 

                q.append(v) 

                result[v] = u, i  

  

    # Если необходимое условие не может быть выполнено

    if dp[0] > 10 ** 9:

        return -1 

    else:  

  

        # Инициализировать новый вектор

        ans = [] 

        u = 0 

        while u != -1:  

  

            # Построение решения путем возврата

            ans.append(result[u][1]) 

            u = result[u][0

          

        # Обратный вектор

        ans = ans[::-1

        for i in ans:  

  

            # Вернуть нужный номер

            return

           
# Код драйвера

if __name__ == "__main__"

   

    arr = [5, 2, 3]  

    n = 12 

  

    print(findSmallestNumber(arr, n)) 

  
# Этот код предоставлен Rituraj Jain

Выход:

2

Рекомендуемые посты:

Наименьшее кратное из N, сформированное с использованием заданного набора цифр

0.00 (0%) 0 votes