描述

题目描述

五种操作

  1. 初始化

输入商品数量, 初始化余额, 输入不同金额纸币的数量

  1. 投币

判断输入的纸币是否合法, 钱够不够, 货有没有

  1. 购买

有没有要的, 有没有货, 钱够不够

  1. 退币

就是从大面额的一顿退

  1. 查询

这个分别 t == 0和 t == 1

然后就是一个非常恶心的大模拟

题解

解法一: 直接模拟

实现思路

这里可以用scanf处理我们的输入, 这样可以保证我们把一些奇奇怪怪的字符用这个去掉

然后我们退币的这个操作是需要考虑的, 这里实现方式很多, 可以直接很多个if实现, 也是可以从大的到小的用一个数组去模拟, 然后最后每次尽可能的减少最后输出

20220212183358

代码实现

#include <bits/stdc++.h>

using namespace std;

vector<int> a(10), cost = {0, 2, 3, 4, 5, 8, 6}, m(11), y = {1, 2, 5, 10};
// 分别是商品, 花费, 钱盒, 面值
int cnt = 0;

void init() {
    scanf("%d-%d-%d-%d-%d-%d %d-%d-%d-%d;", &a[1], &a[2], &a[3], &a[4], &a[5],
          &a[6], &m[1], &m[2], &m[5], &m[10]);
    // 用scanf可以把中间的一些特殊字符搞掉
    cnt = 0;
    // 初始化我们的余额
    puts("S001:Initialization is successful");
}

void push() {
    int coin;
    scanf("%d", &coin);
    // 投入我们的币
    if (not(coin == 1 or coin == 2 or coin == 5 or coin == 10))  // 假币
        puts("E002:Denomination error");
    else if (not(coin == 1 or coin == 2) and m[1] + 2 * m[2] < coin)  // 钱不够
        puts("E003:Change is not enough, pay fail");
    else if (a[1] == 0 and a[2] == 0 and a[3] == 0 and a[4] == 0 and
             a[5] == 0 and a[6] == 0)  // 没了
        puts("E005:All the goods sold out");
    else
        m[coin]++, printf("S002:Pay success,balance=%d\n", cnt += coin);
}

void buy() {
    char op;
    int index;
    scanf(" %c%d", &op, &index);
    if (op != 'A' or index < 1 or index > 6)  // 是否存在
        puts("E006:Goods does not exist");
    else if (a[index] == 0)  // 没货了
        puts("E007:The goods sold out");
    else if (cnt < cost[index])  // 钱不够
        puts("E008:Lack of balance");
    else
        a[index]--, printf("S003:Buy success,balance=%d\n", cnt -= cost[index]);
}

void back() {
    if (cnt == 0) {
        puts("E009:Work failure");
        return;
    }
    vector<int> tmp(4, 0);
    for (int i = 3; i >= 0; i--) {
        tmp[i] = min(cnt / y[i], m[y[i]]);
        m[y[i]] -= tmp[i];
        cnt -= tmp[i] * y[i];
    }
    for (int i = 0; i <= 3; i++) {
        cout << y[i] << " yuan coin number=" << tmp[i] << "\n";
    }
    cnt = 0;
}

void query() {
    int t;
    scanf("%d", &t);
    puts("E010:Parameter error");
    return;
    if (t == 0)
        for (int i = 1; i <= 6; i++) printf("A%d %d %d\n", i, cost[i], a[i]);
    else if (t == 1)
        for (int i = 0; i < 4; i++)
            printf("%d yuan coin number=%d\n", y[i], m[y[i]]);
}

signed main() {
    char c;
    while (scanf("%c", &c) != EOF) {
        // 这样处理可以避免奇奇怪怪的错误
        if (c == 'r') {
            // 这个是我们的初始化操作
            init();
        } else if (c == 'p') {
            // 我们的投币操作
            push();
        } else if (c == 'b') {
            // 购买操作
            buy();
        } else if (c == 'c') {
            // 退币
            back();
        } else if (c == 'q') {
            // 查询
            query();
        }
    }
    return 0;
}

时空复杂度分析

时间复杂度: O(n)O(n)

理由如下: nn条指令, 全都是if语句

空间复杂度: O(1)O(1)

理由如下: 引用额外的常数级别的空间

解法二: 类包装

实现思路

我们可以把操作封装成为一个工具类

代码实现

#include <bits/stdc++.h>

using namespace std;
vector<int> a(10), cost = {0, 2, 3, 4, 5, 8, 6}, m(11), y = {1, 2, 5, 10};
// 分别是商品, 花费, 钱盒, 面值
int cnt = 0;
class Game {
   public:
    void init() {
        scanf("%d-%d-%d-%d-%d-%d %d-%d-%d-%d;", &a[1], &a[2], &a[3], &a[4],
              &a[5], &a[6], &m[1], &m[2], &m[5], &m[10]);
        // 用scanf可以把中间的一些特殊字符搞掉
        cnt = 0;
        // 初始化我们的余额
        puts("S001:Initialization is successful");
    }

    void push() {
        int coin;
        scanf("%d", &coin);
        // 投入我们的币
        if (not(coin == 1 or coin == 2 or coin == 5 or coin == 10))  // 假币
            puts("E002:Denomination error");
        else if (not(coin == 1 or coin == 2) and
                 m[1] + 2 * m[2] < coin)  // 钱不够
            puts("E003:Change is not enough, pay fail");
        else if (a[1] == 0 and a[2] == 0 and a[3] == 0 and a[4] == 0 and
                 a[5] == 0 and a[6] == 0)  // 没了
            puts("E005:All the goods sold out");
        else
            m[coin]++, printf("S002:Pay success,balance=%d\n", cnt += coin);
    }

    void buy() {
        char op;
        int index;
        scanf(" %c%d", &op, &index);
        if (op != 'A' or index < 1 or index > 6)  // 是否存在
            puts("E006:Goods does not exist");
        else if (a[index] == 0)  // 没货了
            puts("E007:The goods sold out");
        else if (cnt < cost[index])  // 钱不够
            puts("E008:Lack of balance");
        else
            a[index]--,
                printf("S003:Buy success,balance=%d\n", cnt -= cost[index]);
    }

    void back() {
        if (cnt == 0) {
            puts("E009:Work failure");
            return;
        }
        vector<int> tmp(4, 0);
        for (int i = 3; i >= 0; i--) {
            tmp[i] = min(cnt / y[i], m[y[i]]);
            m[y[i]] -= tmp[i];
            cnt -= tmp[i] * y[i];
        }
        for (int i = 0; i <= 3; i++) {
            cout << y[i] << " yuan coin number=" << tmp[i] << "\n";
        }
        cnt = 0;
    }

    void query() {
        int t;
        scanf("%d", &t);
        puts("E010:Parameter error");
        return;
        if (t == 0)
            for (int i = 1; i <= 6; i++)
                printf("A%d %d %d\n", i ,cost[i], a[i]);
        else if (t == 1) 
            for (int i = 0; i < 4; i++) 
                printf("%d yuan coin number=%d\n", y[i], m[y[i]]);
    }
};

signed main() {
    Game game;
    char c;
    while (scanf("%c", &c) != EOF) {
        // 这样处理可以避免奇奇怪怪的错误
        if (c == 'r') {
            // 这个是我们的初始化操作
            game.init();
        } else if (c == 'p') {
            // 我们的投币操作
            game.push();
        } else if (c == 'b') {
            // 购买操作
            game.buy();
        } else if (c == 'c') {
            // 退币
            game.back();
        } else if (c == 'q') {
            // 查询
            game.query();
        }
    }
    return 0;
}

时空复杂度分析

时间复杂度: O(n)O(n)

理由如下: nn条指令, 全都是if语句

空间复杂度: O(1)O(1)

理由如下: 引用额外的常数级别的空间