Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.62/55: Рейтинг темы: голосов - 55, средняя оценка - 4.62
 Аватар для Fixer_84
1505 / 969 / 812
Регистрация: 30.04.2016
Сообщений: 3,337

Найти количество N-значных чисел, у которых сумма цифр равна их произведению (оптимизировать код)

02.05.2017, 21:03. Показов 10853. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте! Снова приходится просить помощи уважаемых знатоков. Сам в оптимизации не силен. В этой задаче 2 теста из 10 не прошли по времени. Как-то можно это исправить?

Условие:

N-значные числа

Найти количество N-значных чисел, у которых сумма цифр равна их произведению. Вывести наименьшее среди таких чисел для заданного N (N < 10).

Входные данные:

Число N не превышающее 10.

Выходные данные:

В выходном файле через пробел вывести 2 числа: количество искомых чисел и наименьшее среди них.

Мое решение:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <cmath>
 
using namespace std;
 
bool Num(int N)
{
    int p, sum;
    p = 1;
    sum = 0;
    while (N > 0)
    {
        sum += N % 10;
        p *= N % 10;
        N /= 10;
    }
    if (p == sum)
        return true;
    return false;
}
 
int main()
{
    int N, k, num, a, b;
    cin >> N;
    if (N == 1)
        cout << 10 << " " << 0 << endl;
    else
    {
        k = 0;
        a = pow(10, N - 1);
        b = pow(10, N);
        for (int i = a; i < b; i++)
        {
            if (Num(i))
            {
                k++;
                if (k == 1)
                    num = i;
            }
        }
        cout << k << " " << num << endl;
    }
    system("pause");
    return 0;
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
02.05.2017, 21:03
Ответы с готовыми решениями:

Найти количество N-значных чисел, у которых сумма цифр равна их произведению
Найти количество N- значных чисел , у которых сумма цифр равна их произведению . Назвать наименьшее из чисел для данного. помогите...

Найти количество N-значных натуральных чисел, сумма цифр каждого из которых равняется M (оптимизирвать код)
Здравствуйте, уважаемые знатоки. Мне снова нужна помощь по оптимизации решения. Со сложностью алгоритмов у меня, к сожалению, большие...

Определить количество M-значных натуральных чисел, у которых сумма цифр равна заданному значению
Определить количество M-значных натуральных чисел, у которых сумма цифр, стоящих в нечетных разрядах, равна N (1 \leq N \leq 30, 0 &lt; M...

4
Эксперт .NET
 Аватар для Даценд
5878 / 4755 / 2939
Регистрация: 20.04.2015
Сообщений: 8,361
02.05.2017, 22:29
Цитата Сообщение от Fixer_84 Посмотреть сообщение
Число N не превышающее 10.
или все таки
Цитата Сообщение от Fixer_84 Посмотреть сообщение
(N < 10)
Ибо для десятизначных int мал.
Не знаю, решит ли это проблему, но раза в два ускорит:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <cmath>
 
using namespace std;
 
bool Num(int N, int maxSum)
{
    int p, sum, digit;
    p = 1;
    sum = 0;
    while (N > 0)
    {
        digit = N%10;
        if(!digit) return false;
        sum += digit;
        p *= digit;
        if(p>maxSum) return false;
        N /= 10;
    }
    return p == sum;
}
 
int main()
{
    int N, k, num, a, b;
    cin >> N;
    int maxSum = 9 * N;
    if (N == 1)
        cout << 10 << " " << 0 << endl;
    else
    {
        k = 0;
        a = pow(10, N - 1);
        b = pow(10, N);
        for (int i = a; i < b; i++)
        {
            if (Num(i, maxSum))
            {
                k++;
                if (k == 1)
                    num = i;
            }
        }
        cout << k << " " << num << endl;
    }
    return 0;
}
1
 Аватар для Fixer_84
1505 / 969 / 812
Регистрация: 30.04.2016
Сообщений: 3,337
02.05.2017, 22:45  [ТС]
Спасибо! Один тест удалось исправить, но в последнем по-прежнему 2 секунды (9/10, 90%)
0
354 / 135 / 28
Регистрация: 16.12.2012
Сообщений: 607
Записей в блоге: 1
02.05.2017, 23:52
У Вас неверный подход. Посчитайте сколько операций Вы выполните в худшем случае.
Обычно за 1 секунда заходит 10^6, 10^7, 10^8 (тут уже простых) операций.
У вас же намного больше.
Нужно думать над алгоритмом, а не над оптимизацией. Даже если Вы сдадите - полезных навыков будет в разы меньше, чем от правильного алгоритма.

Попытайтесь придумать сами. Это снова дп.
1
 Аватар для GoldenId
142 / 143 / 64
Регистрация: 11.11.2010
Сообщений: 877
Записей в блоге: 10
03.05.2017, 10:06
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include <cstdint>
#include <iostream>
#include <vector>
 
typedef int64_t myint;
 
// степени десятки: 1, 10, 100, ... 100...0
std::vector<myint> ten_pows;
 
// количество сочетаний из n по m
long long C( int n, int m )
{
    if( n - m > m )
        m = n - m;
    long long c = 1;
    for( int i = n; i > m; i-- )
        c *= i;
    for( int i = n - m; i > 1; i-- )
        c /= i;
    return c;
}
 
// наше условие: сумма цифр равна их произведению
bool cond( myint num )
{
    myint sum = 0;
    myint prod = 1;
    while( num )
    {
        sum += num % 10;
        prod *= num % 10;
        num /= 10;
    }
    return sum == prod;
}
 
void analyzeN( int N )
{
    // предвычислим степени десятки
    ten_pows.resize( N );
    ten_pows[0] = 1;
    for( int d = 1; d < N; d++ )
        ten_pows[d] = 10 * ten_pows[d - 1];
 
    int count = 0;
    myint first = 0;
 
    // сформируем текущее число 11...1 (N раз)
    myint num = 0;
    int d;
    for( d = 0; d < N; d++ )
        num += ten_pows[d];
 
    while( true )
    {
        // если число удовлетворяет условию,
        if( cond( num ) )
        {
            // если это первое встреченное число, запомним его
            if( first == 0 )
                first = num;
            // прибавим к общему количеству чисел, удовлетворяющих условию
            // количество перестановок цифр текущего числа
            int c = 1;  // количество перестановок предыдущих цифр
            int l = 1;  // длина секции одинаковых цифр
            int d = 1;  // номер текущей цифры
            for( ; d < N; d++ )
            {
                if( ( num / ten_pows[d] % 10 ) == ( num / ten_pows[d-1] % 10 ) )
                    l++;
                else
                {
                    c *= C( d, l );
                    l = 1;
                }
            }
            c *= C( d, l );
            count += c;
        }
 
        // возьмём следующее число из отсортированных
        int d = 0;
        for( ; num % 10 == 9; d++ )
            num /= 10;
        if( num == 0 )
            break;
        num++;
        myint digit = num % 10;
        for( ; d > 0; d-- )
            num = num * 10 + digit;
    }
 
    std::cout << "N: " << N << ", first: " << first << ", count: " << count << "\n";
}
 
int main()
{
    for( int N = 1; N <= 18; N++ )
        analyzeN( N );
 
    std::cin.get();
}
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
N: 1, first: 1, count: 9
N: 2, first: 22, count: 1
N: 3, first: 123, count: 6
N: 4, first: 1124, count: 12
N: 5, first: 11125, count: 40
N: 6, first: 111126, count: 30
N: 7, first: 1111127, count: 84
N: 8, first: 11111128, count: 224
N: 9, first: 111111129, count: 144
N: 10, first: 1111111144, count: 45
N: 11, first: 11111111136, count: 605
N: 12, first: 111111112222, count: 495
N: 13, first: 1111111111137, count: 1170
N: 14, first: 11111111111225, count: 1092
N: 15, first: 111111111111138, count: 210
N: 16, first: 1111111111111146, count: 240
N: 17, first: 11111111111111139, count: 2448
N: 18, first: 111111111111111234, count: 4896
Добавлено через 3 минуты
Смысл в том, что рассматриваем только отсортированные по цифрам числа (т.е. d1d2d3..dn, d1<=d2<=d3<=...dn) и при нахождении числа, удовлетворяющего условию, к количеству всех таких чисел добавляем количество разных перестановок его цифр.
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
03.05.2017, 10:06
Помогаю со студенческими работами здесь

Определить количество M-значных натуральных чисел у которых сумма цифр стоящих на нечетных разрядах равна N
Привет всем! Помогите пожалуйста написать программу и составить схему алгоритма по следующему заданию: Определить количество M-значных...

Определить количество М-значных натуральных чисел, у которых сумма цифр, стоящих в нечетных разрядах, равна N
Определить количество М-значных натуральных чисел, у которых сумма цифр, стоящих в нечетных разрядах, равна N (1&lt;N&lt; 30,...

Найти количество n-значных цифр, у которых сумма первой половины равна сумме второй
Добрый вечер , пожалуйста, помогите реализовать такое Посчитать количество n-значных цифр, у которых сумма первой половины равна сумме...

Нужно изменить задачку под код PHP :Среди всех n-значных чисел укажите те,сумма цифр которых равна данному чис
var s1,cod,s,n,k,i,j,a,b:integer; a1:string; Begin ClrScr; Write('Сколько цифр в числе n='); Read(n); Write('Введите число...

Найти все пары чисел, для которых их сумма равна их произведению и количество таких пар
может есть какие-нибудь другие варианты? procedure TForm1.Button1Click(Sender: TObject); var i,j: integer; begin ListBox1.Clear; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru