地址:http://acm.hdu.edu.cn/showproblem.php?pid=2723
题意:为了对一个文件进行访问控制,会给每个文件建立一个访问控制列表(ACL),每个列表里有若干个entity(类似于用户组),每个entity有若干个right(权限)。给出一个文件的权限更改日志,日志是ExR形式的短语构成,E是这次操作影响的entity(多个),R是right,x是一个操作符,可以为+、-、=。为+的时候表示把权限加到entity上,为-的时候表示从entity减去相应权限,为=的时候表示把entity设为相应权限。最后输出每个entity对应的权限,没有权限的不输出,2个相邻的entity如果有相同的权限,合并输出。
mark:这其实就是个阅读题。数据量很小,读懂了几乎就是实现的问题,因为只有26个字母所以用位运算写爽爆了。很2b地wa了2次,一次是sscanf没处理好,一次是数组开小了,而且第三次提交的时候虽然A了,但是看错行以为wa,瞪了1小时不知道错哪儿直到小朋友提醒才发现。。。
代码:
# include <stdio.h> # include <string.h> int ACL[30], out[30][2] ; char str[100] ; char entity[100], right[100] ; void gao(char s[]) { char *p = s, op ; int ent, rit, i, j ; memset (ACL, 0, sizeof(ACL)) ; while (*p) { sscanf (p, "%[A-Z]%c%[a-z]%*c", entity, &op, right) ; p += strlen(entity) + strlen(right) + 2 ; for (i = 0 ; entity[i] ; i++) { ent = entity[i]-'A' ; for (rit = 0, j = 0 ; right[j] ; j++) rit |= (1<<(right[j]-'a')) ; if (op == '+') ACL[ent] |= rit ; else if (op == '-') ACL[ent] &= ~rit ; else //op == '=' ACL[ent] = rit ; } } } int main () { int nCase = 1 ; int i, j, cnt ; while (~scanf ("%s", str) && strcmp(str, "#")) { gao(str) ; memset (str, 0, sizeof(str)) ; printf ("%d:", nCase++) ; for (i = 0, cnt = 0 ; i < 26 ; i++) if (ACL[i]) out[cnt][0] = i, out[cnt++][1] = ACL[i] ; for (i = 0 ; i < cnt ; i++) { printf ("%c", out[i][0]+'A') ; if (i==cnt-1 || (i<cnt-1 && out[i][1] != out[i+1][1])) for (j = 0 ; j < 26 ; j++) if (out[i][1] & (1<<j)) printf ("%c", j+'a') ; } printf (" ") ; } return 0 ; }