Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/140: Рейтинг темы: голосов - 140, средняя оценка - 4.63
0 / 0 / 0
Регистрация: 25.07.2018
Сообщений: 31

Калькулятор с восстановлением ответа

16.11.2018, 22:18. Показов 28098. Ответов 10

Студворк — интернет-сервис помощи студентам
есть задача:
Имеется калькулятор, который выполняет три операции:

Прибавить к числу X единицу.
Умножить число X на 2.
Умножить число X на 3.
Определите кратчайшую последовательность операций, необходимую для получения из числа 1 заданное число N.

Входные данные
Программа получает на вход одно число N, не превосходящее 106.

Выходные данные
Выведите строку, состоящую из цифр "1", "2" или "3", обозначающих одну из трех указанных операций, которая получает из числа 1 число N за минимальное число операций. Если возможных минимальных решений несколько, выведите любое из них. 😁

Пример

Ввод Вывод
1

5
121
562340
3333312222122213312


В сети много решений, но я не могу понять как они работают. Можете пожалуйста объяснить как работает алгоритм этой задачи и как можно решать подобные.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
16.11.2018, 22:18
Ответы с готовыми решениями:

наибольшая общая подпоследовательность с восстановлением ответа
#include <bits/stdc++.h> using namespace std; int main() { ios_base::sync_with_stdio(0); int n, m; cin >> n; ...

Наибольшая общая подпоследовательность с восстановлением ответа
Даны две последовательности, требуется найти и вывести их наибольшую общую подпоследовательность. Формат входных данных В первой...

Калькулятор с восстановлением ответа
Ограничение по времени работы программы: 5 секунд Эта задача аналогична предыдущей задаче «Калькулятор», но в этой задаче требуется также...

10
490 / 286 / 129
Регистрация: 30.10.2018
Сообщений: 1,309
16.11.2018, 22:26
EVGENNIY1337, скорее всего тут просто нужно посчитать сколько операция выполнет каждое дествия по отдельности, к примеру циклом.

Но можно конечно же схитрить, и сделать что-то типо:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int First = N - 1, Second, Third;
 
int temp = 1;
for(int  i = 1 ; temp < N; i++)
{
    temp *= 2;
if(temp == N)
   Second = i;
}//если Second так и не будет инициализировано то умножениям на два нельзя, идентично с тройкой
temp = 1;
for(int  i = 1 ; temp < N; i++)
{
    temp *= 3;
if(temp == N)
   Third= i;
}
0
0 / 0 / 0
Регистрация: 25.07.2018
Сообщений: 31
16.11.2018, 22:43  [ТС]
здесь надо показать в какой последовательности будут происходить операции, и я никак не могу понять, как определить, что нужно сделать, прибавить единицу? умножить на 2? умножить на 3?!
0
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
16.11.2018, 23:22
Цитата Сообщение от EVGENNIY1337 Посмотреть сообщение
я не могу понять как они работают
Скорее всего они основаны на принципе динамического программирования. Просто применяешь его для рекурсивной формулы, которая очевидным образом получается для твоей задачи:
https://www.cyberforum.ru/cgi-bin/latex.cgi?f(n)=\min(f'(n, 2), f'(n, 3), f(n-1)), где https://www.cyberforum.ru/cgi-bin/latex.cgi?f'(n, m)=\begin{cases}<br />
f(n/m) & \text{ if } n \text{ mod } m = 0 \\ <br />
+\infty & \text{ otherwise}  <br />
\end{cases}

Добавлено через 7 минут
а само https://www.cyberforum.ru/cgi-bin/latex.cgi?f(n) - минимальное число операций для получения числа https://www.cyberforum.ru/cgi-bin/latex.cgi?n
0
0 / 0 / 0
Регистрация: 25.07.2018
Сообщений: 31
16.11.2018, 23:39  [ТС]
я не понимаю, что означает +∞ и как вывести именно какие операции применяются
0
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
17.11.2018, 00:32
Лучший ответ Сообщение было отмечено EVGENNIY1337 как решение

Решение

Цитата Сообщение от EVGENNIY1337 Посмотреть сообщение
что означает +∞
Бесконечность. Вся суть функции https://www.cyberforum.ru/cgi-bin/latex.cgi?f'(n,m) - исключить из рассмотрения те числа https://www.cyberforum.ru/cgi-bin/latex.cgi?n, которые не делятся на https://www.cyberforum.ru/cgi-bin/latex.cgi?m (т.е. в твоем случае 2 или 3).

EVGENNIY1337, самый лучший вариант для тебя - открыть книжку, где разбираются задачи на динамическое программирование.

А так, идея следующая. Создаешь массив https://www.cyberforum.ru/cgi-bin/latex.cgi?a длины https://www.cyberforum.ru/cgi-bin/latex.cgi?n, где каждый элемент https://www.cyberforum.ru/cgi-bin/latex.cgi?a_i - минимальное количество операций для получения числа https://www.cyberforum.ru/cgi-bin/latex.cgi?i. Очевидно, что https://www.cyberforum.ru/cgi-bin/latex.cgi?a_1=0. Рассматривать https://www.cyberforum.ru/cgi-bin/latex.cgi?a_2=1,a_3=1,a_4=2,a_5=3 не интересно, так что сразу перескочим к https://www.cyberforum.ru/cgi-bin/latex.cgi?a_6.
Число 6 можно получить тремя способами: умножив какое-то число на 2, умножив какое-то число на 3, и прибавив к какому-то числу 1. Если бы мы воспользовались первым способом, но для получения числа 6 потребовалось бы https://www.cyberforum.ru/cgi-bin/latex.cgi?a_3 + 1 операций, если вторым способом - https://www.cyberforum.ru/cgi-bin/latex.cgi?a_2 + 1 операция, третьим - https://www.cyberforum.ru/cgi-bin/latex.cgi?a_5 + 1. Так как нас интересует минимальное количество операций, то выбираем самое маленькое значение из получившихся https://www.cyberforum.ru/cgi-bin/latex.cgi?a_6=2. С https://www.cyberforum.ru/cgi-bin/latex.cgi?a_7 все еще проще, оно могло получиться только прибавлением единицы, т.е. https://www.cyberforum.ru/cgi-bin/latex.cgi?a_7=a_6+1.

Данная процедура повторяется, пока мы не дойдем до https://www.cyberforum.ru/cgi-bin/latex.cgi?a_n. Для восстановления последовательности операций нужно просмотреть ранее вычисленные значения. Если https://www.cyberforum.ru/cgi-bin/latex.cgi?a_n=k, то число https://www.cyberforum.ru/cgi-bin/latex.cgi?n было получено из числа https://www.cyberforum.ru/cgi-bin/latex.cgi?m\in \{n/2,n/3,n-1\} для которого https://www.cyberforum.ru/cgi-bin/latex.cgi?a_m=k-1 и т.д.
1
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,531
Записей в блоге: 1
17.11.2018, 03:00
Лучший ответ Сообщение было отмечено EVGENNIY1337 как решение

Решение

Цитата Сообщение от EVGENNIY1337 Посмотреть сообщение
Программа получает на вход одно число N, не превосходящее 106.
Цитата Сообщение от EVGENNIY1337 Посмотреть сообщение
562340
3333312222122213312
теги, блджад! теги!

Добавлено через 16 минут
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
#include<iostream>
struct op {
    unsigned count_op;
    unsigned code_op;
    unsigned operand;
}x[1000001];
void print(int operand) {
    if (operand != 1) {
        print(x[operand].operand);
        std::cout << x[operand].code_op;
    }
}
int main()
{
    int N;
    std::cin >> N;
    memset(x, 0xFF, (N+1) * sizeof(op));
    x[1] = { 0 };
    for (int i = 1; i < N; ++i)
    {
        if (x[i + 1].count_op > x[i].count_op + 1)
        {
            x[i + 1].count_op = x[i].count_op + 1;
            x[i + 1].code_op = 1;
            x[i + 1].operand = i;
        }
        if (i*2<=N && x[i*2].count_op > x[i].count_op+1)
        {
            x[i * 2].count_op = x[i].count_op+1;
            x[i * 2].code_op = 2;
            x[i * 2].operand = i;
        }
        if (i * 3 <= N && x[i * 3].count_op > x[i].count_op + 1)
        {
            x[i * 3].count_op = x[i].count_op + 1;
            x[i * 3].code_op = 3;
            x[i * 3].operand = i;
        }
    }
    print(N);
    std::cout << std::endl << ((((1 * 3 * 3 * 3 * 3 * 3 + 1) * 2 * 3 * 3 + 1) * 2 * 2 + 1) * 2 * 2 * 2 + 1) * 2 * 2;
    //даёт разные ответы в сравнении с примером 562340, но оба минимальной длины
    std::cout << std::endl << ((((1 * 3 * 3 * 3 * 3 * 3 + 1) * 2 * 2 * 2 * 2 + 1) * 2 * 2 * 2 + 1) * 3 * 3 + 1) * 2;
    return 0;
}
1
0 / 0 / 0
Регистрация: 25.07.2018
Сообщений: 31
17.11.2018, 16:59  [ТС]
я новичок в программировании. можете пояснить что означает "memset(x, 0xFF, (N+1) * sizeof(op));"
и ".count_op" ".code_op" ".operand"
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,531
Записей в блоге: 1
17.11.2018, 17:11
EVGENNIY1337, а всё остальное понятно что ли? Ну то есть самого главного вопроса, "что это за массив такой" и "почему его индексы умножаются" у тебя не возникло?

Если ты новичок, не знакомый со структурами, то... ну чисто гипотетически можно и без структур подобные этой олимпиадные задачи решать... но зачем?
У тебя жуткие пробелы в знаниях, а ты лезешь в олимпиады по программированию!
0
0 / 0 / 0
Регистрация: 25.07.2018
Сообщений: 31
17.11.2018, 17:17  [ТС]
преступил я к олимпиадному программированию недавно, и структуры мне ещё не требовались, теперь я знаю, что есть такие инструменты, да и что же надо в олимпиадном программировании на начальном уровне? мне кажется не так-то много.
0
0 / 0 / 0
Регистрация: 14.02.2021
Сообщений: 2
23.10.2021, 13:02
Цитата Сообщение от EVGENNIY1337 Посмотреть сообщение
Можете пожалуйста объяснить как работает алгоритм этой задачи и как можно решать подобные.
просто создаем 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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <vector>
#include <set>
#include <queue>
#include <algorithm>
#include <math.h>
using namespace std;
 
vector<int> dp;
vector<int> p;
int e(int a, int b){
    if (a == 0){
        return b;
    }
    return e(b % a, a);
}
 
 
int main(){
    int n;
    cin >> n;
    if (n <= 1){
        return 0;
    }
    dp.resize(7 * n);
    p.resize(7 * n);
    dp[1] = 0;
    for (int i = 1; i <= n + 1; ++i){
        if (dp[i + 1] == 0 || dp[i + 1] > dp[i]){
            dp[i + 1] = dp[i] + 1;
            p[i + 1] = 1;
        }
        if (dp[i * 2] == 0 || dp[i * 2] > dp[i]){
            dp[i * 2] = dp[i] + 1;
            p[i * 2] = 2;
        }
        if (dp[i * 3] == 0 || dp[i * 3] > dp[i]){
            dp[i * 3] = dp[i] + 1;
            p[i * 3] = 3;
        }
    }
    vector<int> ans;
    while (n > 1){
        if (p[n] == 1){
            ans.push_back(1);
            n -= 1;
        } else if (p[n] == 2){
            ans.push_back(2);
            n /= 2;
        } else {
            ans.push_back(3);
            n /= 3;
        }
    }
    for (int i = ans.size() - 1; i >= 0; --i){
        if (ans[i] != 0){
            cout << ans[i];
        }
    }
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
23.10.2021, 13:02
Помогаю со студенческими работами здесь

Калькулятор с восстановлением ответа (Python)
Здравствуйте. В общем, условие такое: *** Исполнитель «Калькулятор» может с заданным числом X выполнить одну из трех операций и ...

Динамическое программирование задача "Калькулятор с восстановлением ответа" (Pascal ABC)
Всем привет. Пишу с проблемой о принятии моей задачи тестирующей программой. Сама задача: Имеется калькулятор, который выполняет три...

Калькулятор: вывод ответа на форму html
Здравствуйте, помогите. Написал калькулятор в одном файле test.php, все работает норм , а мне надо, чтобы в html файле, была форма и...

Калькулятор: вывод ответа, запоминание числа
Пробую написать калькулятор(основываясь на статьи в сети) столкнулся с проблемами:вывод ответа, запоминание числа. ПОМОГИТЕ ПЛИИИЗЗЗ!!

Калькулятор (ввод числа, +, -, *, /, ^, второе число, вывод ответа)
Создайте калькулятор, который принимает число, базовый математический оператор (+, -, *, /, ^) и второе число из пользовательского ввода, и...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru