hdu 2723

地址: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 ;
}
原文地址:https://www.cnblogs.com/lzsz1212/p/3318691.html