CCF-201612-3 -权限查询
問題描述
授權 (authorization) 是各類業務系統不可缺少的組成部分,系統用戶通過授權機制獲得系統中各個模塊的操作權限。
本題中的授權機制是這樣設計的:每位用戶具有若干角色,每種角色具有若干權限。例如,用戶 david 具有 manager 角色,manager 角色有 crm:2 權限,則用戶 david 具有 crm:2 權限,也就是 crm 類權限的第 2 等級的權限。
具體地,用戶名和角色名稱都是由小寫字母組成的字符串,長度不超過 32。權限分為分等級權限和不分等級權限兩大類。分等級權限由權限類名和權限等級構成,中間用冒號“:”分隔。其中權限類名也是由小寫字母組成的字符串,長度不超過 32。權限等級是一位數字,從 0 到 9,數字越大表示權限等級越高。系統規定如果用戶具有某類某一等級的權限,那么他也將自動具有該類更低等級的權限。例如在上面的例子中,除 crm:2 外,用戶 david 也具有 crm:1 和 crm:0 權限。不分等級權限在描述權限時只有權限類名,沒有權限等級(也沒有用于分隔的冒號)。
給出系統中用戶、角色和權限的描述信息,你的程序需要回答多個關于用戶和權限的查詢。查詢可分為以下幾類:
* 不分等級權限的查詢:如果權限本身是不分等級的,則查詢時不指定等級,返回是否具有該權限;
* 分等級權限的帶等級查詢:如果權限本身分等級,查詢也帶等級,則返回是否具有該類的該等級權限;
* 分等級權限的不帶等級查詢:如果權限本身分等級,查詢不帶等級,則返回具有該類權限的等級;如果不具有該類的任何等級權限,則返回“否”。
輸入格式
輸入第一行是一個正整數 p,表示不同的權限類別的數量。緊接著的 p 行被稱為 P 段,每行一個字符串,描述各個權限。對于分等級權限,格式為<category>:<level>,其中?<category>?是權限類名,<level>?是該類權限的最高等級。對于不分等級權限,字符串只包含權限類名。
接下來一行是一個正整數 r,表示不同的角色數量。緊接著的 r 行被稱為 R 段,每行描述一種角色,格式為
<role> <s> <privilege 1> <privilege 2> ... <privilege s>
其中?<role>?是角色名稱,<s>?表示該角色具有多少種權限。后面?<s>?個字符串描述該角色具有的權限,格式同 P 段。
接下來一行是一個正整數 u,表示用戶數量。緊接著的 u 行被稱為 U 段,每行描述一個用戶,格式為
<user> <t> <role 1> <role 2> ... <role t>
其中?<user>?是用戶名,?表示該用戶具有多少種角色。后面 `` 個字符串描述該用戶具有的角色。 接下來一行是一個正整數 q,表示權限查詢的數量。緊接著的 q 行被稱為 Q 段,每行描述一個授權查詢,格式為 `?`,表示查詢用戶 `` 是否具有 `` 權限。如果查詢的權限是分等級權限,則查詢中的 `` 可指定等級,表示查詢該用戶是否具有該等級的權限;也可以不指定等級,表示查詢該用戶具有該權限的等級。對于不分等級權限,只能查詢該用戶是否具有該權限,查詢中不能指定等級。
輸出格式
輸出共 q 行,每行為 false、true,或者一個數字。false 表示相應的用戶不具有相應的權限,true 表示相應的用戶具有相應的權限。對于分等級權限的不帶等級查詢,如果具有權限,則結果是一個數字,表示該用戶具有該權限的(最高)等級。如果用戶不存在,或者查詢的權限沒有定義,則應該返回 false。
樣例輸入?
3
crm:2
git:3
game
4
hr 1 crm:2
it 3 crm:1 git:1 game
dev 2 git:3 game
qa 1 git:2
3
alice 1 hr
bob 2 it qa
charlie 1 dev
9
alice game
alice crm:2
alice git:0
bob git
bob poweroff
charlie game
charlie crm
charlie git:3
malice game
樣例輸出
false
true
false
2
false
true
false
true
false
樣例說明
樣例輸入描述的場景中,各個用戶實際的權限如下:
- 用戶 alice 具有 crm:2 權限
- 用戶 bob 具有 crm:1、git:2 和 game 權限
- 用戶 charlie 具有 git:3 和 game 權限
- 用戶 malice 未描述,因此不具有任何權限
評測用例規模與約定
評測用例規模:
- 1 ≤ p, r, u ≤ 100
- 1 ≤ q ≤ 10?000
- 每個用戶具有的角色數不超過 10,每種角色具有的權限種類不超過 10約定:
- 輸入保證合法性,包括:
1) 角色對應的權限列表(R 段)中的權限都是之前(P 段)出現過的,權限可以重復出現,如果帶等級的權限重復出現,以等級最高的為準
2) 用戶對應的角色列表(U 段)中的角色都是之前(R 段)出現過的,如果多個角色都具有某一分等級權限,以等級最高的為準
3) 查詢(Q 段)中的用戶名和權限類名不保證在之前(U 段和 P 段)出現過
- 前 20% 的評測用例只有一種角色
- 前 50% 的評測用例權限都是不分等級的,查詢也都不帶等級
解題說明
這個題目最后是要查詢用戶權限信息,所以就是要保存<用戶,權限,等級>,還要注意同一個用戶的同一個權限要取最高等級.有三種存入數據的操作和一種查詢數據的操作,只要數據存好了,查詢問題就不大.而且因為題目說好了輸入是合法的,所以其實P段沒什么用,測試用例中Q段可能會違背U段和P段,但是U段不會違背P段,這樣也就簡單了一點。
?
1 #include<bits/stdc++.h> using namespace std;//保存權限信息 2 struct Privilege { 3 string name; 4 int level; 5 }privilege[110]; 6 //保存角色信息 7 struct Role { 8 string name; 9 Privilege privi[11]; 10 int privilege_num; 11 }role[110]; 12 //保存用戶信息 13 struct User { 14 string name; 15 Role role[11]; 16 int rolenum; 17 }usr[110]; 18 int p, u, r, q, pos; 19 string s; 20 //用于查找privilege的下標 21 int findPrivi(string str) { 22 for (int i = 0; i < 100; i++) { 23 if (privilege[i].name == str) 24 return i; 25 } 26 return -1; 27 } 28 //用于查找role的下標 29 int findRole(string str) { 30 for (int i = 0; i < 100; i++) { 31 if (role[i].name == str) 32 return i; 33 } 34 return -1; 35 } 36 //用于查找usr的下標 37 int findUser(string str) { 38 for (int i = 0; i<100; i++) { 39 if (usr[i].name == str) return i; 40 } 41 return -1; 42 } 43 //權限讀入 44 void readPrivi() { 45 for (int i = 0; i < p; i++) { 46 cin >> s; 47 if (s.find(':', 0) == s.npos) { 48 privilege[i].level = -1;//level等于-1代表不分等級權限 49 privilege[i].name = s; 50 } 51 else { 52 pos = s.find(':', 0); 53 privilege[i].name = s.substr(0, pos); 54 privilege[i].level = s[s.length() - 1] - '0'; 55 } 56 } 57 } 58 //角色讀入 59 void readRole() { 60 for (int i = 0; i < r; i++) { 61 cin >> role[i].name; 62 cin >> role[i].privilege_num; 63 for (int j = 0; j < role[i].privilege_num; j++) { 64 cin >> s; 65 if (s.find(':', 0) == s.npos) { 66 role[i].privi[j].level = -1; 67 role[i].privi[j].name = s; 68 } 69 else { 70 pos = s.find(':', 0); 71 role[i].privi[j].name = s.substr(0, pos); 72 role[i].privi[j].level = s[s.length() - 1] - '0'; 73 } 74 } 75 } 76 } 77 //角色讀入 78 void readUser() { 79 for (int i = 0; i < u; i++) { 80 cin >> usr[i].name; 81 cin >> usr[i].rolenum; 82 for (int j = 0; j < usr[i].rolenum; j++) { 83 cin >> s; 84 usr[i].role[j] = role[findRole(s)]; 85 } 86 } 87 } 88 void solve() { 89 string tmp; 90 while (q--) { 91 int t_level = -1;//保存詢問中的權限等級 92 cin >> s >> tmp; 93 int t_usr = findUser(s); 94 if (tmp.find(':', 0) != tmp.npos) { 95 pos = tmp.find(':', 0); 96 t_level = tmp[tmp.length() - 1] - '0'; 97 tmp = tmp.substr(0, pos); 98 } 99 int t_privi = findPrivi(tmp); 100 //如果被查詢的權限名或用戶名不存在,直接輸出false 101 if (t_usr == -1 || t_privi == -1) { 102 cout << "false" << endl; 103 continue; 104 } 105 //詢問中不包含權限等級的情況 106 if (t_level == -1) { 107 //詢問的是分等級權限 108 if (privilege[t_privi].level != -1) { 109 int ans = -1; 110 for (int j = 0; j<usr[t_usr].rolenum; j++) { 111 for (int k = 0; k<usr[t_usr].role[j].privilege_num; k++) { 112 if (usr[t_usr].role[j].privi[k].name == tmp) { 113 ans = max(ans, usr[t_usr].role[j].privi[k].level); 114 } 115 } 116 } 117 if (ans == -1) { 118 cout << "false" << endl; 119 } 120 else 121 cout << ans << endl; 122 } 123 //詢問的是不分等級權限 124 else { 125 int ans = -1; 126 for (int j = 0; j<usr[t_usr].rolenum; j++) { 127 for (int k = 0; k<usr[t_usr].role[j].privilege_num; k++) { 128 if (usr[t_usr].role[j].privi[k].name == tmp) { 129 ans = 1;//代表用戶擁有該權限 130 } 131 } 132 } 133 if (ans == -1) { 134 cout << "false" << endl; 135 } 136 else 137 cout << "true" << endl; 138 } 139 } 140 //詢問中包含權限等級的情況 141 else { 142 int ans = -1; 143 for (int j = 0; j<usr[t_usr].rolenum; j++) { 144 for (int k = 0; k<usr[t_usr].role[j].privilege_num; k++) { 145 if (usr[t_usr].role[j].privi[k].name == tmp) { 146 //遍歷用戶擁有的權限,找到用戶擁有的被查詢權限等級的最大值 147 ans = max(ans, usr[t_usr].role[j].privi[k].level); 148 } 149 } 150 } 151 //用戶擁有的權限比查詢的高 152 if (ans >= t_level) { 153 cout << "true" << endl; 154 } 155 else 156 cout << "false" << endl; 157 } 158 } 159 } 160 int main() { 161 string s; 162 cin >> p; 163 readPrivi(); 164 cin >> r; 165 readRole(); 166 cin >> u; 167 readUser(); 168 cin >> q; 169 solve(); 170 }
?
轉載于:https://www.cnblogs.com/cswangchen/p/7532439.html
總結
以上是生活随笔為你收集整理的CCF-201612-3 -权限查询的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求一个比较污的个性签名
- 下一篇: 有用链接