{ }codelper
standard containersreferencesP0085

A stock ledger passed by reference

Keep a warehouse stock as item name → count in a std::map and process n commands in order.
Write one function per command; functions that change the stock take the map by reference (&), and functions that only read it take a const reference. - add name k: add k of that item and print the new count. - get name: print the count of that item.
For an unknown item print 0 and do not add it to the ledger. - use name k: if there are at least k, remove k and print the count left.
If the count left is 0, delete the item from the ledger.
If there are fewer than k or the item is unknown, change nothing and print -1. After all commands, print the number m of items left in the ledger, then m lines "name count" in dictionary order of the names (plain comparison of lowercase strings).

Input
First line n (1 ≤ n ≤ 1000), then one command per line for n lines.
Names are 1 to 10 lowercase letters, 1 ≤ k ≤ 1000
Output
One line per command, then m, then m lines of "name count"
Example 1 · stdin
7
add apple 5
add kiwi 2
get pear
use apple 3
use kiwi 5
use kiwi 2
get apple
stdout
5
2
0
2
-1
0
2
1
apple 2
main.py
Input (stdin)

When you run, these lines are fed to input()/stdin in order (the program doesn't stop to ask).

$ Ready

Open this on a computer to write and run code. On mobile you can read the problem and the solutions.

In other languagesShow solutions by language · 1 languages

This problem takes C++ only, because choosing references (&) and using the standard container std::map is C++'s own way (Java, C#, Python and JS always pass objects by reference so there is nothing to choose, and C has no map).
Three traps: (1) if a function takes Stock stock without &, the whole map is copied and the counts removed inside the function vanish with the copy.
(2) stock[name] looks like a read but inserts a missing name with 0; used in get, an item you only looked up stays in the final list as pear 0.
Ask with find, and take read-only functions as const Stock& so that [] does not even compile (in add, += starting from 0 is actually handy).
(3) std::unordered_map iterates in hash order, not by name; std::map iterates in key order.
Do not use an iterator after erase(it), so read the count left first.
In Craykon you would do the same with Dict() and Contains, but there is no reference-or-copy choice to make.

C++main.cpp · 45 lines
#include <iostream>#include <map>#include <string> using Stock = std::map<std::string, int>; // 바꾸는 함수는 참조(&)로 받는다: 복사본이 아니라 main의 stock 그 자체int add(Stock& stock, const std::string& name, int k) {    stock[name] += k;  // 없으면 0으로 만들고 더한다 — 여기서는 그게 맞다    return stock[name];} // 읽기만 하는 함수는 const 참조: 복사도 없고, stock[name]처럼 넣어 버리는 코드는 컴파일되지 않는다int get(const Stock& stock, const std::string& name) {    auto it = stock.find(name);    return it == stock.end() ? 0 : it->second;} int use(Stock& stock, const std::string& name, int k) {    auto it = stock.find(name);    if (it == stock.end() || it->second < k) return -1;    it->second -= k;    int left = it->second;    if (left == 0) stock.erase(it);  // erase 뒤에는 it를 쓰지 않는다    return left;} int main() {    int n;    std::cin >> n;    Stock stock;    for (int i = 0; i < n; i++) {        std::string cmd, name;        std::cin >> cmd >> name;        if (cmd == "get") {            std::cout << get(stock, name) << '\n';        } else {            int k;            std::cin >> k;            std::cout << (cmd == "add" ? add(stock, name, k) : use(stock, name, k)) << '\n';        }    }    std::cout << stock.size() << '\n';    for (const auto& [name, qty] : stock) std::cout << name << ' ' << qty << '\n';}