Задача: "Банковские счета"

Некоторый банк хочет внедрить систему управления счетами клиентов, поддерживающую следующие операции:
-пополнение счёта клиента;
-снятие денег со счёта;
-запрос остатка средств на счёте;
-перевод денег между счетами клиентов;
-начисление процентов всем клиентам.
Необходимо реализовать такую систему. Клиенты банка идентифицируются именами (уникальная строка, не содержащая пробелов). Первоначально у банка нет ни одного клиента. Как только для клиента проводится операция пополнения, снятия или перевода денег, ему заводится счёт с нулевым балансом. Все дальнейшие операции проводятся только с этим счётом. Сумма на счету может быть как положительной, так и отрицательной, при этом всегда является целым числом.

Сначала вводится количество проводимых операций n (n <= 50000). Следующие n строк содержат сами операции:

DEPOSIT name sum — зачислить сумму sum на счёт клиента name. Если у клиента нет счёта, то счёт создаётся.
WITHDRAW name sum — снять сумму sum со счёта клиента name. Если у клиента нет счёта, то счёт создаётся.
BALANCE name — узнать остаток средств на счету клиента name.
TRANSFER name1 name2 sum — перевести сумму sum со счёта клиента name1 на счёт клиента name2. Если у какого-либо клиента нет счёта, то ему создаётся счёт.
INCOME p — начислить всем клиентам, у которых открыты счета, p% от суммы счёта. Проценты начисляются только клиентам с положительным остатком на счету, если у клиента остаток отрицательный, то его счёт не меняется. После начисления процентов сумма на счету остается целой, то есть начисляется только целое число денежных единиц. Дробная часть начисленных процентов отбрасывается.

Для каждого запроса BALANCE необходимо вывести остаток на счету данного клиента. Если же у клиента с запрашиваемым именем не открыт счёт в банке, выведите ERROR.
Пример:
Ввод:
7
DEPOSIT Ivanov 100
INCOME 5
BALANCE Ivanov
TRANSFER Ivanov Petrov 50
WITHDRAW Petrov 100
BALANCE Petrov
BALANCE Sidorov
Вывод:
105
-50
ERROR

Я написал код на C++:

#include <iostream>
#include <map>
#include <string>
using namespace std;

void deposit(map<string, long long> &bank, string &name, long long &sum)
{
    if (bank.find(name) == bank.end())
        bank[name] = 0;
    bank[name] += sum;
}
void withdraw(map<string, long long> &bank, string &name, long long &sum)
{
    if (bank.find(name) == bank.end())
        bank[name] = 0;
    bank[name] -= sum;
}
string balance(map<string, long long> &bank, string &name)
{
    if (bank.find(name) == bank.end())
        return "ERROR";
    return to_string(bank[name]);
}
void income(map<string, long long> &bank, float percent)
{
    for (auto it = bank.begin(); it != bank.end(); ++it)
    {
        if (it->second > 0)
        {
            bank[it->first] = it->second * (100 + percent) / 100;
        }
    }
}
int main()
{
    map<string, long long> bank;
    long long n, val; cin >> n;
    string command, name, name2;
    for (long long i = 0; i < n; i++)
    {
        cin >> command;
        if (command == "DEPOSIT")
        {
            cin >> name >> val;
            deposit(bank, name, val);
        }
        else if (command == "WITHDRAW")
        {
            cin >> name >> val;
            withdraw(bank, name, val);
        }
        else if (command == "BALANCE")
        {
            cin >> name;
            cout << balance(bank, name) << endl;
        }
        else if (command == "TRANSFER")
        {
            cin >> name >> name2 >> val;
            withdraw(bank, name, val);
            deposit(bank, name2, val);
        }
        else if (command == "INCOME")
        {
            float value;
            cin >> value;
            income(bank, value);
        }
    }
}

На каком-то из тестов он выводит неверный ответ. Не могу понять, где ошибка. Подскажите пожалуйста, где она может быть и как её можно исправить? (Тестовые данные мне не известны...)


Ответы (1 шт):

Автор решения: Harry

Ну, как говорится, будете смеяться, но...

Я нашел вашу задачу здесь. Кстати, если бы вы привели URL проверяющей системы, а не заставляли искать ее по всему Интернету — все было бы проще и гораздо быстрее...

Там, правда, надо не n вводить, а читать все подряд до конца. Но ваш код и правда давал частичное решение, пока я не переписал одну строчку:

bank[it->first] = it->second * (1.0 + percent/100.0);

После этого все заработало, а меня навело на мысль, что в percent какое-то пере/недо/полнение. Замена в вашем коде float на double действительно спасла ситуацию.

И еще — проверки на существование при оформлении вклада/снятия излишни, этот код вполне работает:

void deposit(map<string, long long> &bank, string &name, long long &sum)
{
    bank[name] += sum;
}
void withdraw(map<string, long long> &bank, string &name, long long &sum)
{
    bank[name] -= sum;
}
→ Ссылка