Skip to content

Pro3

原始文件为 CPP 代码,本文是转换后的 Markdown 文件。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <map>
#include <vector>
#include <sstream>

using namespace std;

int main()
{
    string line;    
    //freopen("in.txt","r",stdin);

    map<string,int> usernamemap;
    vector<vector<int> > usercontainer;
    map<string,int> rolenamemap;
    vector<map<string,int> > rolecontainer;

    int privnum; scanf("%d",&privnum);  cin.get();
    for (int i = 0; i < privnum; ++i){  getline(cin,line);  }

    int rolenum; scanf("%d",&rolenum);  cin.get();
    for (int i = 0; i < rolenum; ++i)
    {
        getline(cin,line);
        stringstream ss(line);
        string rolename;
        int privcount;      
        ss >> rolename >> privcount;

        rolenamemap.insert(make_pair(rolename,rolecontainer.size()));
        map<string,int> thisRolePriv;

        for (int j = 0; j < privcount; ++j)
        {
            string privname;
            int privlevel;
            ss >> privname;

            int pos = privname.find(':');
            if (pos == -1) 
            {
                privlevel = -1;
            }
            else
            {
                privlevel = stoi(privname.substr(pos+1,privname.size()));
                privname = privname.substr(0,pos);
            }
            if (!thisRolePriv.count(privname) > 0)
            {
                thisRolePriv.insert(make_pair(privname,privlevel));
            }else if (thisRolePriv.count(privname) > 0 && thisRolePriv[privname] < privlevel)
            {
                thisRolePriv[privname] = privlevel;
            }
        }
        rolecontainer.push_back(thisRolePriv);  
    }

    int usernum; scanf("%d",&usernum); cin.get();
    for (int i = 0; i < usernum; ++i)
    {
        string username;
        string line;
        int rolecount;
        getline(cin,line);
        stringstream ss(line);
        ss >> username >> rolecount;

        vector<int> thisUserRole;
        usernamemap.insert(make_pair(username,usercontainer.size()));

        for (int j = 0; j < rolecount; ++j)
        {
            string rolename;
            ss >> rolename;
            thisUserRole.push_back(rolenamemap[rolename]);
        }       
        usercontainer.push_back(thisUserRole);
    }

    int searchnum; scanf("%d",&searchnum); cin.get();
    for (int i = 0; i < searchnum; ++i)
    {
        string user,priv;
        cin >> user >> priv;

        if (!usernamemap.count(user) > 0)
        {
            cout << "false" << endl;
            continue;
        }
        int userorder = usernamemap[user];
        int rolesize = usercontainer[userorder].size();

        string privname;
        int privlevel;

        int pos = priv.find(':');
        if (pos == -1) 
        {
            privlevel = -1;
            privname = priv;
        }
        else
        {
            privlevel = stoi(priv.substr(pos+1,priv.size()));
            privname = priv.substr(0,pos);
        }

        bool flag = true;
        bool returnNum = false;
        int max = 0;

        for (int j = 0; j < rolesize; ++j)
        {
            int c = rolecontainer[ usercontainer[userorder][j] ].count(privname);

            if (c > 0)
            {
                int reallevel = rolecontainer[ usercontainer[userorder][j] ][privname];
                //cout << user << " " << privname << " " << reallevel << " " << privlevel << endl;
                if (reallevel == -1 && privlevel == -1)
                {
                    cout << "true" << endl;
                    flag = false;
                    break;
                }
                if (reallevel > -1 && privlevel > -1 && privlevel <= reallevel)
                {
                    cout << "true" << endl;
                    flag = false;
                    break;
                }
                if (reallevel > -1 && privlevel == -1)
                {
                    if (max < reallevel) max = reallevel;
                    flag = false;
                    returnNum = true;
                }
                if (reallevel == -1 && privlevel > -1)
                {
                    break;
                }
            }
        }

        if (flag) cout << "false" << endl;
        if (returnNum) cout << max << endl;
    }
}