数据结构课程设计 15 设计电影租借系统

问题描述 :

你有一个电影租借公司和 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指令返回的二维数组,分多行输出,每个输出的整数后跟一个空格。

 

核心思路:双结构体互相包含指向对方的指针,一对多与多对一的对应关系。

Movie_Store 包含Movie*类型的vector,存储指向其所拥有电影的指针;

Movie 包含Movie_Store*类型的指针,代表其所属的电影商店的指针,并使用ms_number指代其所属电影商店的序号,方便查找,减少一重指针调用。

#include <bits/stdc++.h>
using namespace std;

struct Movie;
struct Movie_Store;

struct Movie
{
    int data;
    int value;
    Movie_Store *ms;
    int ms_number;
    bool rent_if = false;
};

struct Movie_Store
{
    int flag;
    vector<Movie *> M;
};

vector<Movie_Store> MS;

bool cmp1(Movie a, Movie b)
{
    if (a.value != b.value)
    {
        return a.value < b.value;
    }
    else
    {
        return a.ms_number < b.ms_number;
    }
}

void Search(int find_data)
{
    int len = MS.size();
    vector<Movie> result;

    for (int i = 0; i < len; i++)
    {
        int len_m = MS[i].M.size();
        for (int j = 0; j < len_m; j++)
        {
            if (MS[i].M[j]->data == find_data && MS[i].M[j]->rent_if == false)
            {
                result.push_back(*MS[i].M[j]);
            }
        }
    }

    sort(result.begin(), result.begin() + result.size(), cmp1);

    int len_result = result.size();
    if (len_result > 5)
    {
        len_result = 5;
    }

    bool f = false;
    for (int i = 0; i < len_result; i++)
    {
        cout << result[i].ms_number << " ";
    }
    cout << endl;
}

void Rent(int s, int m)
{
    int result_ms;
    int len = MS.size();

    for(int i=0;i<len;i++)
    {
        if(MS[i].flag == s)
        {
            result_ms = i;
        }
    }
    
    int len_m = MS[result_ms].M.size();

    for (int i = 0; i < len_m; i++)
    {
        if (MS[result_ms].M[i]->data == m)
        {
            MS[result_ms].M[i]->rent_if = true;
            break;
        }
    }
}

void Drop(int s, int m)
{
    int result_ms;
    int len = MS.size();

    for(int i=0;i<len;i++)
    {
        if(MS[i].flag == s)
        {
            result_ms = i;
        }
    }
    
    int len_m = MS[result_ms].M.size();

    for (int i = 0; i < len_m; i++)
    {
        if (MS[result_ms].M[i]->data == m)
        {
            MS[result_ms].M[i]->rent_if = false;
            break;
        }
    }
}

bool cmp2(Movie a, Movie b)
{
    if (a.value != b.value)
    {
        return a.value < b.value;
    }

    else if (a.ms_number != b.ms_number)
    {
        return a.ms_number < b.ms_number;
    }

    else
    {
        return a.data < b.data;
    }
}

void Report()
{
    int len = MS.size();
    vector<Movie> result;

    for (int i = 0; i < len; i++)
    {
        for (int j = 0; j < MS[i].M.size(); j++)
        {
            if (MS[i].M[j]->rent_if == true)
            {
                result.push_back(*MS[i].M[j]);
            }
        }
    }

    sort(result.begin(), result.begin() + result.size(), cmp2);

    int len_result = result.size();
    if (len_result > 5)
    {
        len_result = 5;
    }

    for (int i = 0; i < len_result; i++)
    {
        cout << result[i].ms_number << " " << result[i].data << " " << endl;
    }
}

int main()
{
    int n, m;
    cin >> n >> m;

    for (int i = 0; i < m; i++)
    {
        Movie *movie = new Movie;
        cin >> movie->ms_number;
        cin >> movie->data;
        cin >> movie->value;

        int len = MS.size();
        int f = -1;
        for (int j = 0; j < len; j++)
        {
            if (movie->ms_number == MS[j].flag)
            {
                f = j;
                break;
            }
        }

        if (f != -1)
        {
            movie->ms = MS.data() + f;
            MS[f].M.push_back(movie);
        }

        else
        {
            Movie_Store *ms0 = new Movie_Store;
            ms0->flag = movie->ms_number;
            ms0->M.push_back(movie);

            movie->ms = ms0;

            MS.push_back(*ms0);

            ms0 = NULL;
        }

        movie = NULL;
    }

    string str;
    while (cin >> str)
    {
        if (str == "search")
        {
            int p;
            cin >> p;
            Search(p);
        }

        else if (str == "rent")
        {
            int p, q;
            cin >> p >> q;
            Rent(p, q);
        }

        else if (str == "drop")
        {
            int p, q;
            cin >> p >> q;
            Drop(p, q);
        }

        else
        {
            Report();
        }
    }

    return 0;
}

又及:这份代码又名为《我不是针对任何一个人,我是指,我是在场的全部的各位的妈》、《打一晚上de一上午过关斩将最终死在八万个测试用例前的TLE题》

如果不改算法的话,目前队友给出的优化思路是 1.采用scanf输入减少输入时间 2.采用插入排序,不用sort排序 3.试试哈希表能不能活

如有优化思路,欢迎评论指出,我还可以继续秃头.gif

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值