Форум программистов, компьютерный форум, киберфорум
Алгоритмы
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.72/32: Рейтинг темы: голосов - 32, средняя оценка - 4.72
0 / 0 / 0
Регистрация: 18.09.2013
Сообщений: 24

Количество n-значных чисел

22.03.2015, 17:40. Показов 7625. Ответов 68
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Задано натуральные числа N и M.

Посчитайте количество N-значных натуральных чисел, сумма цифр в которых равна M.

Значения N и M (1 ≤ N ≤ 9, 1 ≤ M ≤ 81).
Как решить задачу? Разложить на множители?

Заранее благодарю!
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
22.03.2015, 17:40
Ответы с готовыми решениями:

В потоке чисел найти количество положительных и отрицательных 2у значных чисел, не используя массив
В потоке чисел найти количество положительных и отрицательных 2у значных чисел, не используя массив

Дана последовательность целых чисел, последнее из которых 0. Найти количество 3-значных чисел
Дана последовательность целых чисел, последнее из которых 0. Найти количество 3-значных чисел. cout << "Dano: "...

Количество n - значных чисел
На входе программы имеем натуральное число n. Вывести количество n - значных ннатуральных чисел. Что то не так с этим кодом , подскажите...

68
09.04.2015, 17:27
Студворк — интернет-сервис помощи студентам

Не по теме:

Кликните здесь для просмотра всего текста
Цитата Сообщение от Shamil1 Посмотреть сообщение
И любую программу на F# я могу практически один в один переписать на C#
на C# не переписывается 1-в-1: pattern-matching, measures, typeproviders, object expressions, ADT, duck typing, dsl'ы, рекурсии, мож еще что забыл. все это либо в принципе не рализуемо через C# (typeproviders), либо будет иметь существенные отличия в реализации (размер, читабельность, скорость, безопасность типизации).
Цитата Сообщение от Shamil1 Посмотреть сообщение
Можете предложить другую задачу для сравнения.
да легко
http://ideone.com/1bYwgG
http://ideone.com/aTFee9
с# переписанный 1-в-1 с f#. разница только в том что с# не работает

впрочем это не тот раздел форума что б сравнивать

0
Модератор
Эксперт функциональных языков программирования
3141 / 2289 / 469
Регистрация: 26.03.2015
Сообщений: 8,915
09.04.2015, 21:38
pycture, спасибо
0
835 / 643 / 101
Регистрация: 20.08.2013
Сообщений: 2,524
09.04.2015, 22:34
Цитата Сообщение от pycture Посмотреть сообщение
разница только в том что с# не работает
Красиво
А почему две функции? С одной работало что ли?
0
Модератор
Эксперт функциональных языков программирования
3141 / 2289 / 469
Регистрация: 26.03.2015
Сообщений: 8,915
09.04.2015, 23:13
_Ivana,
Я так понимаю, что Вы используете формулу:
https://www.cyberforum.ru/cgi-bin/latex.cgi?M(n) = 1 - \sum_{k=2}^{n}M(\frac{n}{k})

Если считать "в лоб", то у меня такой же результат получается.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private static Dictionary<long, long> cache = new Dictionary<long, long>();
 
// рекуррентная формула
private static long MertensRecursiveBasic(long n)
{
    long res;
    if (cache.TryGetValue(n, out res))
        return res;
    
    res = 1;
    for (int k = 2; k <= (int)n; k++)
        res -= MertensRecursiveBasic(n / k);
    
    cache[n] = res;
    return res;
}
Code
1
M(10 000 000) = 1037 - time: 03.7157972 рекуррентная формула
А с оптимизацией - примерно в 1000 раз быстрее.
0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
09.04.2015, 23:32
Я использовал 2 разные формулы, как у же писал выше. Приведенную вами и другую получше. И мой код по вашей формуле без мемоизации считает
Code
1
M(100000) = -48 - time: 4.3442485s
. Если у вас она же демонстрирует озвученный вами результат для M(10 000 000), тогда я пока не могу соревноваться с вами в скорости. Надо получше узнать свой язык и методы оптимизации и ускорения, даже мутабл вектор почему-то не оправдал моих ожиданий, или я неправильно его приготовил.

UPD понял, это ваш результат с кешированием. Мой считает это же 18 секунд по вашей формуле и 4.8 по другой.
0
Модератор
Эксперт функциональных языков программирования
3141 / 2289 / 469
Регистрация: 26.03.2015
Сообщений: 8,915
10.04.2015, 00:33
Цитата Сообщение от Qwertiy Посмотреть сообщение
Красиво
А почему две функции? С одной работало что ли?
С одной c# умеет раскручивать хвостовую рекурсию.

Добавлено через 38 минут
Цитата Сообщение от _Ivana Посмотреть сообщение
Я использовал 2 разные формулы, как у же писал выше. Приведенную вами и другую получше. И мой код по вашей формуле без мемоизации считает
Code
1
M(100000) = -48 - time: 4.3442485s
. Если у вас она же демонстрирует озвученный вами результат для M(10 000 000), тогда я пока не могу соревноваться с вами в скорости. Надо получше узнать свой язык и методы оптимизации и ускорения, даже мутабл вектор почему-то не оправдал моих ожиданий, или я неправильно его приготовил.

UPD понял, это ваш результат с кешированием. Мой считает это же 18 секунд по вашей формуле и 4.8 по другой.
Вы можете скачать LinqPad и запустить мой код, чтобы сравнить производительность наших компьютеров. (У меня ноутбук).


А другая формула - это, наверное, та же, но суммирование только для нечётных https://www.cyberforum.ru/cgi-bin/latex.cgi?k?

Формула:
https://www.cyberforum.ru/cgi-bin/latex.cgi?M(n) = 1 - \sum_{k=2}^{n}M(\frac{n}{k})
получается из свойства
https://www.cyberforum.ru/cgi-bin/latex.cgi?\sum_{k=1}^{n}M(\frac{n}{k}) = 1

Из того же свойства для чётных членов:
https://www.cyberforum.ru/cgi-bin/latex.cgi?\sum_{i=1}^{n/2}M(\frac{n}{2i}) = \sum_{i=1}^{n/2}M(\frac{n/2}{i}) = 1
Значит можно суммировать только для нечётных https://www.cyberforum.ru/cgi-bin/latex.cgi?k, а сумму для чётных заменить на 1.

У меня такая оптимизация даёт ускорение примерно в 3.5 раза.

Но есть ещё оптимизация, которая улучшает сложность алгоритма. Так как https://www.cyberforum.ru/cgi-bin/latex.cgi?\frac{n}{k} принимает всего примерно https://www.cyberforum.ru/cgi-bin/latex.cgi?2 \sqrt{n} различных значений, мы можем разбить сумму на два диапазона, сгруппировав во втором по одинаковым https://www.cyberforum.ru/cgi-bin/latex.cgi?\frac{n}{k}.
https://www.cyberforum.ru/cgi-bin/latex.cgi?M(n) = 1 - \sum_{k=2}^{\sqrt{n}}M(\frac{n}{k}) - \sum_{k=2}^{\sqrt{n}}(\frac{n}{k} - \frac{n}{k+1}))M(k)

Ну и последняя оптимизация - моя любимая , которую я пытаюсь провести для любого рекурсивного алгоритма с кэшированием. Это построение снизу в вверх с заменой хэш-таблицы на массив. В данном случае я считал заранее не все значения, а только от 1 до https://www.cyberforum.ru/cgi-bin/latex.cgi?\sqrt{n}, которые нам точно понадобятся.

Code
1
2
3
4
5
M(10 000 000) = 1037 - time: 03.7580821 рекуррентная формула
M(10 000 000) = 1037 - time: 01.0583190 рекуррентная формула нечётные
M(10 000 000) = 1037 - time: 00.0507118 рекуррентная формула группировка
M(10 000 000) = 1037 - time: 00.0239988 рекуррентная формула нечётные группировка
M(10 000 000) = 1037 - time: 00.0043729 рекуррентная формула нечётные группировка решето

Code
1
2
3
4
5
M(100 000 000) = 1928 - time: 42.2252041 рекуррентная формула
M(100 000 000) = 1928 - time: 11.6501233 рекуррентная формула нечётные
M(100 000 000) = 1928 - time: 00.2900044 рекуррентная формула группировка
M(100 000 000) = 1928 - time: 00.1363545 рекуррентная формула нечётные группировка
M(100 000 000) = 1928 - time: 00.0186478 рекуррентная формула нечётные группировка решето
(простые варианты выросли в 11 раз, варианты с группировкой в 6 раз, а с решетом всего в 4 раза)


Полный код:
Кликните здесь для просмотра всего текста
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
void Main()
{
    int n = 100000;
    const string template = @"M({0:n0}) = {1} - time: {2:ss'.'fffffff} {3}";
    var timer = new Stopwatch();
    
    cache.Clear();
    timer.Restart();
    var res1 = MertensRecursiveBasic(n);
    timer.Stop();
    Console.WriteLine(template, n, res1, timer.Elapsed, "рекуррентная формула");
 
    cache.Clear();
    timer.Restart();
    cache.Add(1, 1);
    var res2 = MertensRecursiveOdd(n);
    timer.Stop();
    Console.WriteLine(template, n, res2, timer.Elapsed, "рекуррентная формула нечётные");
 
    cache.Clear();
    timer.Restart();
    var res3 = MertensRecursiveSqrt(n);
    timer.Stop();
    Console.WriteLine(template, n, res3, timer.Elapsed, "рекуррентная формула группировка");
 
    cache.Clear();
    timer.Restart();
    cache.Add(1, 1);
    var res4 = MertensRecursiveSqrtOdd(n);
    timer.Stop();
    Console.WriteLine(template, n, res4, timer.Elapsed, "рекуррентная формула нечётные группировка");
 
 
    cache.Clear();
    timer.Restart();
    var len = (int)(Math.Sqrt(n)*Math.Log(n + 3)) + 3;
    mertens = GetMertens(len);  
    var res5 = MertensRecTableSqrtOdd(n);
    timer.Stop();
    Console.WriteLine(template, n, res5, timer.Elapsed, "рекуррентная формула нечётные группировка решето");
 
}
 
// Define other methods and classes here
private static Dictionary<long, long> cache = new Dictionary<long, long>();
private static int[] mertens = new int[] {0,1,0};
 
// рекуррентная формула
private static long MertensRecursiveBasic(long n)
{
    long res;
    if (cache.TryGetValue(n, out res))
        return res;
    
    res = 1;
    for (int k = 2; k <= (int)n; k++)
        res -= MertensRecursiveBasic(n / k);
    
    cache[n] = res;
    return res;
}
 
// рекуррентная формула нечётные
private static long MertensRecursiveOdd(long n)
{
    long res;
    if (cache.TryGetValue(n, out res))
        return res;
    
    res = 0;
    for (int k = 3; k <= (int)n; k+=2)
        res -= MertensRecursiveOdd(n / k);
    
    cache[n] = res;
    return res;
}
 
// M(n) = 1 - sum [<=sqrt] ( M(n/k) ) - sum [<=sqrt] ( (n/k - n/(k + 1))*M(k) )
// рекуррентная формула корень
        private static long MertensRecursiveSqrt(long n)
        {
            long res;
            if (cache.TryGetValue(n, out res))
                return res;
 
            int sqrt = (int)Math.Sqrt(n);
            res = 1;
            for (int k = 2; k <= sqrt; k++)
                res -= MertensRecursiveSqrt(n / k);
            for (int k = 1; n / k > sqrt; k++)
                res -= (n / k - n / (k + 1)) * MertensRecursiveSqrt(k);
 
            cache[n] = res;
            return res;
        }
 
        // рекуррентная формула корень нечётные
 
        // M(n) = 1 - sum odd [<=sqrt] ( M(n/k) ) - sum [<=sqrt] ( (n/k - n/(k + 1))*M(k) )
        private static long MertensRecursiveSqrtOdd(long n)
        {
            long res;
            if (cache.TryGetValue(n, out res))
                return res;
 
            int sqrt = (int)Math.Sqrt(n);
            res = 0;
            for (int k = 3; k <= sqrt; k += 2)
                res -= MertensRecursiveSqrtOdd(n / k);
            for (long k = 1, nk = n, nk1; nk > sqrt; k++, nk = nk1)
            {
                nk1 = n / (k + 1);
                res -= (nk - (nk >> 1) - nk1 + (nk1 >> 1)) * MertensRecursiveSqrtOdd(k);
            }
            cache[n] = res;
            return res;
        }
 
        // решето
        private static int[] GetMertens(int max)
        { 
            var sqrt = (int)Math.Floor(Math.Sqrt(max));
            var mu = new int[max + 1];
            for (int i = 1; i <= max; i++)
                mu[i] = 1;
            for (int i = 2; i <= sqrt; i++)
            {
                if (mu[i] == 1)
                {
                    for (int j = i; j <= max; j += i)
                        mu[j] *= -i;
                    for (int j = i * i; j <= max; j += i * i)
                        mu[j] = 0;
                }
            }
            for (int i = 2; i <= max; i++)
            {
                if (mu[i] == i)
                    mu[i] = 1;
                else if (mu[i] == -i)
                    mu[i] = -1;
                else if (mu[i] < 0)
                    mu[i] = 1;
                else if (mu[i] > 0)
                    mu[i] = -1;
                mu[i] += mu[i - 1];
            }
            return mu;
        }
        
        
        // рекуррентная формула корень нечётные таблица
 
        // M(n) = 1 - sum odd [<=sqrt] ( M(n/k) ) - sum [<=sqrt] ( (n/k - n/(k + 1))*M(k) )
        private static long MertensRecTableSqrtOdd(long n)
        {
            if (n < mertens.Length) return mertens[n];
            long res;
            if (cache.TryGetValue(n, out res))
                return res;
 
            int sqrt = (int)Math.Sqrt(n);
            res = 0;
            for (int k = 3; k <= sqrt; k += 2)
                res -= MertensRecTableSqrtOdd(n / k);
            for (long k = 1, nk = n, nk1; nk > sqrt; k++, nk = nk1)
            {
                nk1 = n / (k + 1);
                res -= (nk - (nk >> 1) - nk1 + (nk1 >> 1)) * MertensRecTableSqrtOdd(k);
            }
            cache[n] = res;
            return res;
        }
0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
10.04.2015, 00:55
Результаты для Мертенса впечатляют. Хотя я не пробовал более радикальные формулы и оптимизации. Но на все случаи жизни не напасешься, например ваш подход провалится на задачах типа Задача про функцию или где аргументы надо явно хешировать-переводить в число, а не сразу имеем один целочисленный аргумент. Но конечно это не отменяет как ваших успехов на этом поприще, так и моей необходимости разбираться со своим инструментом. Например, буквально час назад я по другому поводу вспомнил, что у меня по-умолчанию все ленивое и ничего не вычисляется пока не нужно, и надо специальные ухищрения применять если что-то надо вычислять строго по ходу пьесы (просьба не ерничать по этому поводу известных любителей строгости в противовес, так сказать )
0
10.04.2015, 06:00

Не по теме:

Цитата Сообщение от Qwertiy Посмотреть сообщение
А почему две функции? С одной работало что ли?
потому как взаимную рекурсию просто так в цикл не развернешь, а обычную запросто. да и с JIT оптимизациями там тоже чтото было

0
Модератор
Эксперт функциональных языков программирования
3141 / 2289 / 469
Регистрация: 26.03.2015
Сообщений: 8,915
10.04.2015, 19:28
Цитата Сообщение от _Ivana Посмотреть сообщение
например ваш подход провалится на задачах типа Задача про функцию
Да уж, тут не предскажешь, какие нужно считать.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
10.04.2015, 19:28

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

Найти количество n-значных чисел
Всем привет. У меня есть число n. Я его заполняю с клавиатуры: int n; cin&gt;&gt;n; и как мне посчитать количество n-значных чисел?

Количество натуральных N-значных чисел
Сколько натуральных N-значных чисел начинаются с цифры A или цифры B? подскажите пожалуйста формулу

Подсчитать количество 6-значных чисел
1)Составить программу, печатающие такие номера счастливых билетов, которые равны квадрату какого-либо натурального числа. (это сделано ,...

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


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

Или воспользуйтесь поиском по форуму:
69
Ответ Создать тему
Новые блоги и статьи
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru