📌  相关文章
📜  门| Sudo GATE 2020 Mock I(2019 年 12 月 27 日)|问题 13(1)

📅  最后修改于: 2023-12-03 15:28:47.228000             🧑  作者: Mango

门 | Sudo GATE 2020 Mock I(2019 年 12 月 27 日)|问题 13

介绍

题目链接:https://www.geeksforgeeks.org/gate-cs-2020-mock-i-question-13/

这是2020年GATE计算机科学的一道模拟题,问题13要求我们设计一个门系统,该门系统可以依据授权,对不同的人员进行门禁管理。

详解

我们可以通过该门系统来实现对不同用户进行门禁管理,该门系统需要实现三个函数:

  • void addPerson(int id, int auth):添加一个ID为id的人员,其授权等级为auth
  • void removePerson(int id):移除ID为id的人员;
  • bool canPass(int id, int auth):返回是否允许ID为id的人员通过该门系统,其授权等级为auth

我们可以使用哈希表来进行人员ID的存储,其中授权等级可以使用一维数组来存储,数组的下标表示授权等级,数组的值为含有该授权等级的人员ID的哈希表。(因为授权等级很少,所以不建议使用二维数组来存储)

具体实现代码如下:

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

const int N=1e5+5;
unordered_map<int,int>mp[N];// 存储不同等级授权的编号
unordered_map<int,int>vis;// 记录编号是否存在
int n;// 总共有多少人

void addPerson(int id, int auth){
    if(id>n||vis[id]) return;// 若编号大于总人数或者编号已在系统中,直接返回
    mp[auth][id]=1;
    vis[id]=1;
}

void removePerson(int id){
    if(id>n||!vis[id]) return;
    for(int i=1;i<=n;i++)
        if(mp[i].count(id))// 找到编号的等级,将其从相应的授权哈希表中删除
            mp[i].erase(id);
    vis.erase(id);// 将该编号从已存储的编号中删除
}

bool canPass(int id, int auth){
    if(id>n||!vis[id]) return false;
    for(int i=auth;i<=n;i++)// 从输入的auth开始查找授权等级
        if(mp[i].count(id)) return true;// 找到该编号在该授权等级的哈希表中
    return false;
}

int main(){
    n=5;
    addPerson(1,1);
    addPerson(2,2);
    addPerson(3,3);
    addPerson(4,4);
    addPerson(5,5);
    removePerson(3);
    assert(canPass(2,3)==false);// 虽然2的授权等级为2,但其不能去到3的区域
    assert(canPass(2,2)==true);
    assert(canPass(6,2)==false);
    return 0;
}

其中,我们在 main 函数中设置了五个不同编号的人,他们的授权等级分别为1-5。我们移除了编号为3的人,此时数字3的授权在哈希表中被删除,之后我们对 canPass 函数进行三组测试,其中第一组为检查输入分享阶级不同是否会根据系统不允许人员进入的情况,第二组检查具有相同授权等级的人员是否允许进入,第三组检查系统是否对不存在的人进行校验。

总结

通过使用哈希表和数组的方式,我们可以很方便地实现门禁系统,授权等级和人员ID之间通过哈希表互相映射,同时我们利用哈希表的清晰结构,很容易更新和查找相应的关键字,实现了比较高效的门禁系统。