15 设计电影租借系统
题目链接 力扣
作者: Turbo时间限制: 1S章节: 课程设计
问题描述 :
你有一个电影租借公司和 n 个电影商店。你想要实现一个电影租借系统,它支持查询、预订和返还电影的操作。同时系统还能生成一份当前被借出电影的报告。
所有电影用二维整数数组 entries 表示,其中 entries[i] = [shopi, moviei, pricei] 表示商店 shopi 有一份电影 moviei 的拷贝,租借价格为 pricei 。每个商店有 至多一份 编号为 moviei 的电影拷贝。
系统需要支持以下操作:
Search:找到拥有指定电影且 未借出 的商店中 最便宜的 5 个 。商店需要按照 价格 升序排序,如果价格相同,则 shopi 较小 的商店排在前面。如果查询结果少于 5 个商店,则将它们全部返回。如果查询结果没有任何商店,则返回空列表。
Rent:从指定商店借出指定电影,题目保证指定电影在指定商店 未借出 。
Drop:在指定商店返还 之前已借出 的指定电影。
Report:返回 最便宜的 5 部已借出电影 (可能有重复的电影 ID),将结果用二维列表 res 返回,其中 res[j] = [shopj, moviej] 表示第 j 便宜的已借出电影是从商店 shopj 借出的电影 moviej 。res 中的电影需要按 价格 升序排序;如果价格相同,则 shopj 较小 的排在前面;如果仍然相同,则 moviej 较小 的排在前面。如果当前借出的电影小于 5 部,则将它们全部返回。如果当前没有借出电影,则返回一个空的列表。
请你实现 MovieRentingSystem 类:
MovieRentingSystem(int n, vector<vector<int>>& entries) 将 MovieRentingSystem 对象用 n 个商店和 entries 表示的电影列表初始化。
vector<int> search(int movie) 如上所述,返回 未借出 指定 movie 的商店列表。
void rent(int shop, int movie) 从指定商店 shop 借出指定电影 movie 。
void drop(int shop, int movie) 在指定商店 shop 返还之前借出的电影 movie 。
vector<vector<int>> report() 如上所述,返回最便宜的 5部已借出 电影列表。
注意:测试数据保证 rent 操作中指定商店拥有 未借出 的指定电影,且 drop 操作指定的商店 之前已借出 指定电影。
示例 1:
输入:
3 6
0 1 5
0 2 6
0 3 7
1 1 4
1 2 7
2 1 5
search 1
rent 0 1
rent 1 2
report
drop 1 2
search 2
输出:
1 0 2
0 1
1 2
0 1
解释:
MovieRentingSystem movieRentingSystem = new MovieRentingSystem(3, [[0, 1, 5], [0, 2, 6], [0, 3, 7], [1, 1, 4], [1, 2, 7], [2, 1, 5]]);
movieRentingSystem.search(1); // 返回 [1, 0, 2] (在结果中输出一行),商店 1,0 和 2 有未借出的 ID 为 1 的电影。商店 1 最便宜,商店 0 和 2 价格相同,所以按商店编号排序。
movieRentingSystem.rent(0, 1); // 从商店 0 借出电影 1 。现在商店 0 未借出电影编号为 [2,3] 。
movieRentingSystem.rent(1, 2); // 从商店 1 借出电影 2 。现在商店 1 未借出的电影编号为 [1] 。
movieRentingSystem.report(); // 返回 [[0, 1], [1, 2]] (在结果中输出两行)。商店 0 借出的电影 1 最便宜,然后是商店 1 借出的电影 2 。
movieRentingSystem.drop(1, 2); // 在商店 1 返还电影 2 。现在商店 1 未借出的电影编号为 [1,2] 。
movieRentingSystem.search(2); // 返回 [0, 1](在结果中输出一行) 。商店 0 和 1 有未借出的 ID 为 2 的电影。商店 0 最便宜,然后是商店 1 。
输入说明 :
输入若干行:
第一行两个整数n和m,n表示电影商店的个数,m表示用于初始化对象的entries数组的行数。
然后m行,每行输入三个整数shopi, moviei, pricei表示entries的每一行。
后面有若干行,每行输入为search、rent、drop或report其中之一:
如果指令为search类型,后面需要输入一个整数表示movie。
如果指令为rent类型,后面需要输入两个整数表示shop和movie。
如果指令为drop类型,后面需要输入两个整数表示shop和movie。
如果指令为report类型,后面不需要输入整数。
提示:
1 <= n <= 3 * 10^5
1 <= m <= 10^5
0 <= shopi < n
1 <= moviei, pricei <= 10^4
每个商店 至多 有一份电影 moviei 的拷贝。
search,rent,drop 和 report 的调用 总共 不超过 10^5 次。
输出说明 :
输出若干行:
每行为search或report指令的返回值。
search指令返回的数组,输出每个整数后跟一个空格。
report指令返回的二维数组,分多行输出,每个输出的整数后跟一个空格。
————————————————
版权声明:本文为CSDN博主「杨骅麟(Patrick Young)」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Ultravioletrays/article/details/125476663
// 15 设计电影租借系统.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
#include <unordered_set>
#include <set>
#include <unordered_map>
#include <queue>
using namespace std;
class object {
public:
long long shop, movie, price;
object(long long shop=0, long long movie=0, long long price=0) :shop(shop), movie(movie), price(price) {}
bool operator< (const object& b) const{
if (price != b.price)
return price < b.price;
if(shop!=b.shop)
return shop < b.shop;
return movie < b.movie;
}
bool operator> (const object& b) const {
if (price != b.price)
return price > b.price;
if (shop != b.shop)
return shop > b.shop;
return movie > b.movie;
}
};
bool cmp(const object& a,const object& b) {
if (a.price != b.price)
return a.price > b.price;
if (a.shop != b.shop)
return a.shop > b.shop;
return a.movie > b.movie;
}
class MovieRentingSystem {
unordered_map<int, unordered_map<int, int>>movies;//电影id-商店,价格
unordered_map<int, unordered_map<int, bool>>rented;//电影id-商店,是否借出
multiset<object>rentedlist;
public:
MovieRentingSystem(int n, vector<vector<int>>& entries) {
for (auto&& i : entries)movies[i[1]][i[0]] = i[2];
}
vector<int> search(int movie) {
vector<object>vec;
vector<int>ans;
for (auto&& it : movies[movie]) {
if (rented[movie][it.first])continue;
vec.push_back(object(it.first, movie, it.second));
}
sort(vec.begin(), vec.end());
int times = vec.size();
times = min(5, times);
for (int i = 0; i < times;i++)ans.push_back(vec[i].shop);
return ans;
}
void rent(int shop, int movie) {
rented[movie][shop] = true;
object obj(shop, movie, movies[movie][shop]);
rentedlist.insert(obj);
}
void drop(int shop, int movie) {
rented[movie][shop] = false;
object obj(shop, movie, movies[movie][shop]);
rentedlist.erase(obj);
}
vector<vector<int>> report() {
vector<vector<int>>ans;
priority_queue<object,vector<object>,greater<object>>heap;
for (auto&& it : rentedlist)heap.push(it);
int times = min(5, (int)heap.size());
vector<int>tmp(2);
for (int i = 0; i < times; ++i) {
tmp[0] = heap.top().shop;
tmp[1] = heap.top().movie;
heap.pop();
ans.push_back(tmp);
}
return ans;
}//heap
};
int main()
{
int n, m;
cin >> n >> m;
vector<vector<int>> entries(m, vector<int>(3));
for (int i = 0; i < m; ++i)cin >> entries[i][0] >> entries[i][1] >> entries[i][2];
MovieRentingSystem system(n, entries);
string cmd;
while (cin>>cmd)
{
if (cmd == "search") {
int movie;
cin >> movie;
auto arr= system.search(movie);
for (auto&& i : arr)cout << i << " ";
cout << endl;
}
if (cmd == "rent") {
int shop, movie;
cin >> shop >> movie;
system.rent(shop, movie);
}
if (cmd == "drop") {
int shop, movie;
cin >> shop >> movie;
system.drop(shop, movie);
}
if (cmd == "report") {
auto arr = system.report();
for (auto&& i : arr) {
for (auto&& j : i) {
cout << j << " ";
}
cout << endl;
}
}
}
return 0;
}