hdu 2723 Electronic Document Security

The Tyrell corporation uses a state-of-the-art electronic document system that controls all aspects of document creation, viewing, editing, and distribution. Document security is handled via access control lists (ACLs). An ACL defines a set of entities that have access to the document, and for each entity defines the set of rights that it has. Entities are denoted by uppercase letters; an entity might be a single individual or an entire division. Rights are denoted by lowercase letters; examples of rights are a for append, d for delete, e for edit, and r for read.

The ACL for a document is stored along with that document, but there is also a separate ACL log stored on a separate log server. All documents start with an empty ACL, which grants no rights to anyone. Every time the ACL for a document is changed, a new entry is written to the log. An entry is of the form ExR, where E is a nonempty set of entities, R is a nonempty set of rights, and x is either "+", "–", or "=". Entry E+R says to grant all the rights in R to all the entities in E, entry E–R says to remove all the rights in R from all the entities in E, and entry E=R says that all the entities in E have exactly the rights in R and no others. An entry might be redundant in the sense that it grants an entity a right it already has and/or denies an entity a right that it doesn't have. A log is simply a list of entries separated by commas, ordered chronologically from oldest to most recent. Entries are cumulative, with newer entries taking precedence over older entries if there is a conflict.

Periodically the Tyrell corporation will run a security check by using the logs to compute the current ACL for each document and then comparing it with the ACL actually stored with the document. A mismatch indicates a security breach. Your job is to write a program that, given an ACL log, computes the current ACL.
 

Input
The input consists of one or more ACL logs, each 3–79 characters long and on a line by itself, followed by a line containing only "#" that signals the end of the input. Logs will be in the format defined above and will not contain any whitespace.
 

Output
For each log, output a single line containing the log number (logs are numbered sequentially starting with one), then a colon, then the current ACL in the format shown below. Note that (1) spaces do not appear in the output; (2) entities are listed in alphabetical order; (3) the rights for an entity are listed in alphabetical order; (4) entities with no current rights are not listed (even if they appeared in a log entry), so it's possible that an ACL will be empty; and (5) if two or more consecutive entities have exactly the same rights, those rights are only output once, after the list of entities.
 

Sample Input
  
  
MC-p,SC+c YB=rde,B-dq,AYM+e GQ+tju,GH-ju,AQ-z,Q=t,QG-t JBL=fwa,H+wf,LD-fz,BJ-a,P=aw #
 

Sample Output
  
  
1:CSc 2:AeBerMeYder 3:

4:BHJfwLPaw

题意:首先给你文件集合(大写的),然后给你文件的属性(小写字母),‘+’是给文件加上其属性,‘-’是减去其属性,‘=’是把其原来的属性覆盖掉。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;

char s[110],s1[110];
int Map[30][30];
int i,j,k,l,l1,f;
struct node {
    char c;
    char a[30];
} e[30];
int main() {
    int kase = 0;
    while(cin>>s && strcmp(s,"#")){
        memset(Map,0,sizeof(Map));//存第i行的j属性是否存在
        l=strlen(s);
        l1=0;
        for(i=0;i<l;i++){
            if(s[i]==','){
                memset(s1,0,sizeof(s1));
                l1=0;
            }
            else if(s[i]=='+'){
                for(j=i+1;  s[j]!=','&& j<l;j++){//找到文件的属性
                    for(k=0;k<l1;k++){
                        Map[s1[k]-'A'][s[j]-'a']=1;//第i行的j属性存在

                    }
                }
            }
            else if(s[i]=='-'){
                for(j=i+1;  s[j]!=','&& j<l;j++){
                    for(k=0;k<l1;k++){
                        Map[s1[k]-'A'][s[j]-'a']=0;//第i行的j属性不存在

                    }
                }
            }
            else if(s[i]=='='){
                for(k=0;k<l1;k++){
                    memset(Map[s1[k]-'A'],0,sizeof(Map[0]));//先把之前存在的属性清空
                    for(j=i+1; s[j]!=','&&j<l ;j++)
                         Map[s1[k]-'A'][s[j]-'a']=1;
                }
            }

            else s1[l1++]=s[i];//s1存的是文件
        }
    for(i=0;i<27;i++){
          e[i].c=0;
          memset(e[i].a,0,sizeof(e[i].a));//赋初始值
       }
    l=l1=0;
    for(i=0; i<27; i++) {
        l1=f=0;
        for(j=0; j<27; j++) {
            if(Map[i][j]>0) {
                // printf("i=%d j=%d\n",i,j);
                e[l].c=i+'A';
                //  printf("e[l].c=%c\n",e[l].c);
                e[l].a[l1++]=j+'a';
                f=1;
            }
        }
        if(f)
            l++;
        // if(l1)
        // printf("%s*\n",e[l-1].a);
    }//把结果从Map里面读出来
    printf("%d:",++kase);
    for(i=0; i<l; i++) {
        printf("%c",e[i].c);
        if(strcmp(e[i].a,e[i+1].a)==0)
            continue;
        else
            cout<<e[i].a;
    }
    printf("\n");
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值