С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/55: Рейтинг темы: голосов - 55, средняя оценка - 4.64
0 / 0 / 0
Регистрация: 30.10.2017
Сообщений: 18
1

Размен монет, общий случай

11.06.2019, 09:35. Показов 10443. Ответов 11
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Имеется задача, где задается сумма N, и ее нужно разменять монетами
В коде ниже у нас известны номиналы монет (2, 5, 10)
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
#include <iostream> 
    
using namespace std;
    
int main() 
{   
    int n;
    cin >> n;
    for (int i = 0; i <= n / 2; i++)
    {
            int remainder2 = n - i * 2;
            for (int j = 0; j <= remainder2 / 5; j++)
            {
                int remainder25 = remainder2 - j * 5;
                if (remainder25 % 10 == 0)
                {
                    for (int l = 0; l < i; l++)
                        cout << 2 << ' ';
                    for (int l = 0; l < j; l++)
                        cout << 5 << ' ';
                    for (int l = 0; l < remainder25 / 10; l++)
                        cout << 10 << ' ';
                    cout << endl;
                }
            }
    }
    system("pause");
    return 0;       
}
А как решить ее для общего случая, когда номиналы монет не известны заранее?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.06.2019, 09:35
Ответы с готовыми решениями:

Размен монет
Доброго времени суток! Дана следующая задача: имеется неограниченное количество монет; любая...

Рекурсивная функция размен монет(перевести с Pascal на С++)
C помощью рекурсивной функции разменять заданную сумму денег на монеты заданного номинала,...

размен монет
сколькими способами можно разместить 10-копеечную монету монетами 1,2,3 и 5 копеек при условии, что...

Размен монет
помогите сделать После закупки в большом универмаге Мелу досталась сдача в размере 17 центов. Он...

11
6770 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
11.06.2019, 10:46 2
Цитата Сообщение от RomchK Посмотреть сообщение
А как решить ее для общего случая, когда номиналы монет не известны заранее?
Можно рекусивно перебрать все варианты. Туповатый метод, но рабочий
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
static const uintmax_t _coins[] = {50, 20, 15, 10, 5, 3, 2};
 
inline
bool ChangeSum(uintmax_t sum, std::vector<uintmax_t> &change, size_t idx = 0)
{
    if (idx >= std::size(_coins))
        return false;
 
    const auto nom = _coins[idx];
    if (sum == nom)
    {
        change.emplace_back(nom);
        return true;
    }
 
    if (sum > nom)
    {
        change.emplace_back(nom);
        if (ChangeSum(sum - nom, change, idx) || ChangeSum(sum - nom, change, idx + 1))
            return true;
        change.pop_back();
    }
 
    return ChangeSum(sum, change, idx + 1);
}
1
0 / 0 / 0
Регистрация: 30.10.2017
Сообщений: 18
11.06.2019, 11:22  [ТС] 3
oleg-m1973, спасибо большое, очень выручаете, но есть несколько вопросов:
1) inline здесь используется чисто для повышения производительности?
2) uintmax_t в данном случае нужен для слишком больших значений, которые long long уже не тянет?
3) не совсем понял:
C++
1
2
3
4
5
6
const auto nom = _coins[idx];
    if (sum == nom)
    {
        change.emplace_back(nom);
        return true;
    }
Здесь проверяется равенство суммы и определенного номинала, и затем номинал помещается в конец вектора?
0
6770 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
11.06.2019, 11:26 4
Цитата Сообщение от RomchK Посмотреть сообщение
1) inline здесь используется чисто для повышения производительности?
Нет, просто так. Можно static
Цитата Сообщение от RomchK Посмотреть сообщение
uintmax_t в данном случае нужен для слишком больших значений, которые long long уже не тянет?
Нет. Просто беззнаковое целое (знаковые здесь не нужны)
Цитата Сообщение от RomchK Посмотреть сообщение
Здесь проверяется равенство суммы и определенного номинала, и затем номинал помещается в конец вектора?
Если остаток суммы равен текущему номиналу, можно дольше не проверять - добавляем текущий в результат и выходим
1
0 / 0 / 0
Регистрация: 30.10.2017
Сообщений: 18
11.06.2019, 11:50  [ТС] 5
oleg-m1973, еще раз благодарю

Добавлено через 18 минут
oleg-m1973, извините, не сразу заметил
Здесь pop_back() используется для того, чтобы убрать те номиналы, которые мы уже не будем использовать?
0
6770 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
11.06.2019, 11:54 6
Цитата Сообщение от RomchK Посмотреть сообщение
oleg-m1973, извините, не сразу заметил
Здесь pop_back() используется для того, чтобы убрать те номиналы, которые мы уже не будем использовать?
Это значит, что с последним номиналом размен не получится. Убираем его и пробуем со следующим. Например 11 = 5+5 ->5+3+3
0
0 / 0 / 0
Регистрация: 30.10.2017
Сообщений: 18
11.06.2019, 12:05  [ТС] 7
oleg-m1973, правильно ли я понимаю, что change здесь - вектор номиналов, который заполняется значениями, которое лежат в константном массиве?
0
6770 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
11.06.2019, 12:09 8
Цитата Сообщение от RomchK Посмотреть сообщение
oleg-m1973, правильно ли я понимаю, что change здесь - вектор номиналов, который заполняется значениями, которое лежат в константном массиве?
Правильно. Но необязадельно в константном, можешь сделать обычный массив, только лучше отсортировать его по убыванию, ну и вот здесь поправить if (idx >= std::size(_coins))
0
0 / 0 / 0
Регистрация: 30.10.2017
Сообщений: 18
11.06.2019, 12:21  [ТС] 9
oleg-m1973, а получается данная функция возвращает инфу о возможности обмена?
0
6770 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
11.06.2019, 12:23 10
Цитата Сообщение от RomchK Посмотреть сообщение
oleg-m1973, а получается данная функция возвращает инфу о возможности обмена?
Не знаю, наверное. Если не смогла разменять - вернёт false
0
365 / 321 / 219
Регистрация: 21.02.2013
Сообщений: 756
11.06.2019, 13:12 11
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
#include <iostream>
 
using namespace std;
int main()
{
   int nominals[] = {50, 20, 10, 5, 2, 1};
 
   int sum;
   cout << "Enter Sum: ";
   cin >> sum;
   int i = 0, amount;
   while(sum > 0){
        if(sum >= nominals[i]){
            amount = sum / nominals[i];
 
            cout << "V summe deneg soderzitsa: " << amount << " monet(a) nominalom "
            << nominals[i] << " kopeek" << endl;
            sum = sum - amount * nominals[i];
            i++;
        }
        else{
            i++;
        }
   }
}
0
-11 / 0 / 0
Регистрация: 04.03.2019
Сообщений: 11
10.12.2019, 08:35 12
oleg-m1973, можете помочь почти с подобной задачей
0
10.12.2019, 08:35
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.12.2019, 08:35
Помогаю со студенческими работами здесь

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

Размен монет
Имеется n рублей. Требуется разменять данную сумму, если в кассе есть купюры 10 руб, 100 руб, 50...

Размен суммы с наименьшим количеством монет
Есть такая олимпиадная задача. Всё понятно из темы. Но, жадный алгоритм либо слишком долог, либо в...

CAPICOM или общий случай про third-part dll
необходимо ли устанаваливать CAPICOM на машину клиента, если используешь библиотеку CAPICOM? ...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru