文件操作
时间限制: 1000ms
空间限制: 262144KB
输入文件名: 202506F.in
输出文件名: 202506F.out
题目背景
清羽购置了一台自动贩卖机放在广场上,这台自动贩卖机有一个用户数据库和商品数据库。
用户数据库记录当前用户的用户名,密码,以及当前充值的余额,并且存在两种用户,管理员和普通用户,管理员当然只有清羽一个人。用户名和密码均为字符串。
商品数据库中记录商品的名字和种类,以及价格、库存和购买次数。商品名字和种类均为字符串,价格为整数。
初始时仅有一个管理员账号,账号密码均为admin
,但注意,自动贩卖机一开始没有处于用户登录状态。
这台自动贩卖机有如下操作:
题目描述
register
注册功能:用户需要输入账号和密码,并且注册的账号不能和用户数据库当中已有的账号相同。login
登录功能:使用该功能首先需要用户处在非登录状态,用户需要输入已经注册到用户数据库当中的账号和密码进行登录logout
登出功能:可以让用户从当前登录状态下退出登录。recharge
充值功能:可以进行充值,自动贩卖机仅支持10元,5元,2元,1元的充值buy
购买功能:自动贩卖机可以通过用户充值的余额进行商品的购买change
找零功能:自动贩卖机可以将购买商品后剩余的钱通过找零10,5,2,1元的方式退回用户。restock
建议补货功能:自动贩卖机会检查当前是否需要补货list
商品排列功能:用户可以根据选择进行排列。- 如果某次操作指令并不属于上述指令,则返回
unknown command
输入格式
第一行输入nn表示自动贩卖机有nn个商品
接下来nn行每行输入namename,categorycategory,priceprice,stockstock,分别表示商品名,商品种类,商品价格和商品的初始库存
接下来一行输入mm表示mm次操作,初始时仅有一个管理员账号,账号密码均为admin
,但注意,自动贩卖机一开始没有处于用户登录状态。
在每次操作中:
register
操作需要再输入namename和passwordpassword表示注册用户的账号和密码
login
操作需要再输入namename和passwordpassword表示登录用户的账号和密码
logout
操作表示登出当前账号
recharge
操作需要再输入一个整数xx表示当前投币充值的面额
buy
操作需要再输入一个namename表示购买的商品名
change
操作表示为当前用户余额进行找零
restock
操作仅限管理员使用,表示查看是否需要补货
list
操作表示排列当前商品,需要再输入一个字符串all
表示按照初始输入顺序全部排列,hot
表示按照热销进行排列,其余字符串视为种类,表示排列当前种类的商品(按照初始输入顺序排列)
输出格式
register
操作中,如果当前输入的用户名存在,则输出user exists
,否则完成注册输出register ok
login
操作如果已经处于登录情况则输出logged in
,如果登录成功输出user in
,否则输入login failed
logout
操作如果用户并没有处于登录状态输出user out
,在登出时,如果用户还有余额需要对用户找钱,仅限找零面额为[10,5,2,1][10,5,2,1]由大到小输出,例如找零13元可以输出change: 10x1 2x1 1x1
,change:
后面格式为【面额】x【数量】,如果用户没有余额则不用找零。退出后输出user out
。
recharge
操作如果用户未登录输入please login
,如果用户充值面额并非[1,2,5,10][1,2,5,10]输出:invalid coin
;充值完毕后输出"balance:
+当前用户余额。
buy
操作如果用户未登录输入please login
,如果输入的商品未找到输出product not found
, 如果当前商品库存不够输出sold out
,并退出。如果用户余额不够输出not enough money
。购买完毕后输出buy
+商品名
change
操作为用户登录状态下的找零操作,如果用户未登录输入please login
,如果用户如果有余额输出与logout
操作输出类似,如果没有余额,输出00
restock
操作如果用户未登录输入please login
,如果用户非管理员输出not Admin
,之后遍历所有商品,如果存在库存少于3个的情况输出yes
否则输出no
list
操作如输出格式所述,如果输入字符串为all
或其他种类字符串,输出每行分别显示当前商品的名字,种类,价格,库存和购买数量。如果输入字符串为hot
执行对所有商品按照购买次数进行从大到小的稳定排序,如果购买次数相同按照商品名的字典序从小到大进行稳定排序。排序买行显示当前商品和当前购买次数,中间用空格隔开
样例
Input 1
5 a c1 1 10 b c2 2 10 c c1 1 10 d c2 3 10 e c2 1 10 12 register user1 123456 login admin admin recharge 10 buy b change list hot logout restock login user1 123456 buy c restock login admin admin
Output 1
register ok user in balance: 10 buy b change: 5x1 2x1 1x1 b 1 a 0 c 0 d 0 e 0 user out please login user in not enough money not Admin logged in
数据范围
样例 | n | m | 性质 |
---|---|---|---|
1−31−3 | ≤10≤10 | ≤30≤30 | 样例仅有管理员账号和购买操作 |
4−54−5 | ≤10≤10 | ≤1000≤1000 | 样例包含有其他账号 |
6−76−7 | ≤10≤10 | ≤3000≤3000 | 样例包含有检查是否有库存和找零操作 |
8−108−10 | ≤10≤10 | ≤3000≤3000 | 样例包含有排列操作 |
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 1e3 + 5;
struct User {
string name;
string pwd;
bool isAdmin;
int blance;
} user[N];
struct Product {
string name;
string category;
int price;
int stock;
int cnt;
} product[N], tmp[N];
int usercnt, productCnt;
int checkUser = -1;
int coin[] = {10, 5, 2, 1};
void reg(string n, string p) {
for (int i = 1; i <= usercnt; i++) {
if (user[i].name == n) {
cout << "user exists\n";
return ;
}
}
user[++usercnt] = {n, p, 0, 0};
cout << "register ok\n";
}
void login(string n, string p) {
if (checkUser != -1) {
cout << "logged in\n";
return ;
}
for (int i = 1; i <= usercnt; i++) {
if (user[i].name == n && user[i].pwd == p) {
checkUser = i;
cout << "user in\n";
return ;
}
}
cout << "login failed\n";
}
void logout() {
if (checkUser == -1) {
cout << "user out\n";
return ;
}
//退出时自动找零
int bal = user[checkUser].blance;
if (bal > 0) {
cout << "change:";
int res = bal;
for (int i = 0; i < 4; i++) {
int cnt = res / coin[i];
res %= coin[i];
if (cnt > 0) {
cout << " " << coin[i] << "x" << cnt;
}
}
cout << '\n';
user[checkUser].blance = 0;
}
checkUser = -1;
cout << "user out\n";
}
//充值
void recharge(int amt) {
if (checkUser == -1) {
cout << "please login\n";
return ;
}
if (amt != 1 && amt != 2 && amt != 5 && amt != 10) {
cout << "invalid coin\n";
return ;
}
user[checkUser].blance += amt;
cout << "balance: " << user[checkUser].blance << '\n';
}
void cmd_rank() {
for (int i = 1; i <= productCnt; i++) {
tmp[i] = product[i];
}
stable_sort(tmp + 1, tmp + 1 + productCnt, [](Product a, Product b) {
if (a.cnt != b.cnt) return a.cnt > b.cnt;
return a.name < b.name;
});
for (int i = 1; i <= productCnt; i++) {
cout << tmp[i].name << ' ' << tmp[i].cnt << '\n';
}
}
void buyproduct(string n) {
if (checkUser == -1) {
cout << "please login\n";
return;
}
int idx = -1;
for (int i = 1; i <= productCnt; i++) {
if (product[i].name == n) {
idx = i;
break;
}
}
if (idx == -1) {
cout << "product not found\n";
return ;
}
Product &p = product[idx];
if (p.stock <= 0) {
cout << "sold out\n";
return;
}
if (user[checkUser].blance < p.price) {
cout << "not enough money\n";
return ;
}
user[checkUser].blance -= p.price;
p.stock--;
p.cnt++;
cout << "buy " << p.name << '\n';
}
void restock() {
if (checkUser == -1) {
cout << "please login\n";
return;
}
if (!user[checkUser].isAdmin) {
cout << "not Admin\n";
return ;
}
bool need = 0;
//如果有小于3件商品就需要补货建议
for (int i = 1; i <= productCnt; i++) {
if (product[i].stock <= 3) {
need = 1;
break;
}
}
cout << (need ? "yes" : "no") << '\n';
}
void cmt_list(string arg) {
if (arg == "all") {
//全部列出
for (int i = 1; i <= productCnt; i++) {
Product &p = product[i];
cout << p.name << ' ' << p.category
<< ' ' << p.price << ' ' << p.stock
<< ' ' << p.cnt << '\n';
}
} else if (arg == "hot") {
cmd_rank();
} else {
for (int i = 1; i <= productCnt; i++) {
Product &p = product[i];
if (p.category == arg) {
cout << p.name << ' ' << p.category
<< ' ' << p.price << ' ' << p.stock
<< ' ' << p.cnt << '\n';
}
}
}
}
int main(void)
{
freopen("202506F.in", "r", stdin);
freopen("202506F.out", "w", stdout);
int n;
cin >> n;
productCnt = n;
for (int i = 1; i <= n; i++) {
cin >> product[i].name
>> product[i].category
>> product[i].price
>> product[i].stock;
product[i].cnt = 0;
}
user[++usercnt] = {"admin", "admin", 1, 0};
int m;
cin >> m;
while (m--) {
string op;
cin >> op;
string n, p;
if (op == "register") {
cin >> n >> p;
reg(n, p);
} else if (op == "login") {
cin >> n >> p;
login(n, p);
} else if (op == "logout") {
logout();
} else if (op == "recharge") {
int amt;
cin >> amt;
recharge(amt);
} else if (op == "buy") {
string name;
cin >> name;
buyproduct(name);
} else if (op == "change") {
if (checkUser == -1) {
cout << "please login\n";
} else {
int bal = user[checkUser].blance;
if (bal > 0) {
cout << "change:";
int res = bal;
for (int i = 0; i < 4; i++) {
int cnt = res / coin[i];
res %= coin[i];
if (cnt > 0) {
cout << " " << coin[i] << "x" << cnt;
}
}
cout << '\n';
user[checkUser].blance = 0;
} else {
cout << "0\n";
}
}
} else if (op == "restock") {
restock();
} else if (op == "list") {
string arg;
cin >> arg;
cmt_list(arg);
} else {
cout << "unknown command\n";
}
}
return 0;
}