• POJ 3654 & ZOJ 2936 & HDU 2723 Electronic Document Security(模拟)


    题目链接:

    PKU:http://poj.org/problem?id=3654

    ZJU:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2936

    HDU:http://acm.hdu.edu.cn/showproblem.php?pid=2723


    Description

    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 appendd for deletee 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 ER 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

    Source


    题意:

    运算符(“‘+’, ‘-’, ''=”)前面是名字,‘+’表示把后面的权力赋给前面的人,‘-’表示从前面的人中减去后面的权力(当然没有就不减),‘=’表示把前面的人的权力先清空在把后面的权力赋给前面的人!输出的时候有同样权力的相邻两个人就名字一起输出,再一起输出权力!假设都没有权力则不输出!

    代码例如以下:

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <iostream>
    using namespace std;
    const int maxn = 57;
    int a[maxn][maxn];
    
    int main()
    {
        string tt;
        char str[1017];
        int cas = 0;
        int num[maxn];
        while(scanf("%s",str)!=EOF)
        {
            int len = strlen(str);
            if(len == 1 && str[0] == '#')
                break;
            tt = "";
            memset(a,0,sizeof a);
            for(int i = 0; i < len; i++)
            {
                if(str[i]==',')
                    tt = "";//清空
                else if(str[i] == '+')
                {
                    for(int j = i+1; str[j]!=',' && j < len; j++)
                    {
                        for(int k = 0; k < tt.size(); k++)
                        {
                            a[tt[k]-'A'][str[j]-'a']=1;
                        }
                    }
                }
                else if(str[i] == '-')
                {
                    for(int j = i+1; str[j]!=',' && j < len; j++)
                    {
                        for(int k = 0; k < tt.size(); k++)
                        {
                            a[tt[k]-'A'][str[j]-'a']=0;
                        }
                    }
                }
                else if(str[i] == '=')
                {
                    for(int k = 0; k < tt.size(); k++)
                    {
                        memset(a[tt[k]-'A'],0,sizeof a[0]);
                        for(int j = i+1; str[j]!=',' && j < len; j++)
                        {
                            a[tt[k]-'A'][str[j]-'a']=1;
                        }
                    }
                }
                else
                    tt+=str[i];
            }
            printf("%d:",++cas);
            int l = 0;
            for(int i = 0; i < 26; i++)//记录下全部有权力的人
            {
                int flag = 0;
                for(int j = 0; j < 26; j++)
                {
                    if(a[i][j])
                        flag = 1;
                }
                if(flag)
                {
                    num[l++] = i;
                }
            }
    
            tt = "";
            for(int i = 0; i < l; i++)
            {
                int flag = 0;
                if(i != l-1)
                {
                    for(int j = 0; j < 26; j++)
                    {
                        if(a[num[i]][j] != a[num[i+1]][j])//所含的权力不同
                        {
                            flag = 1;
                        }
                    }
                }
                char tem = 'A'+num[i];
                tt += tem;
                if(flag==1 || i==l-1)
                {
                    cout<<tt;
                    tt = "";
                    for(int j = 0; j < 26; j++)
                    {
                        if(a[num[i]][j])
                            printf("%c",'a'+j);
                    }
                }
            }
            printf("
    ");
        }
        return 0;
    }
    


  • 相关阅读:
    分解质因数
    大素数测试和分解质因数
    快速幂
    欧拉函数
    素数
    gcd,lcm,ext_gcd,inv
    凸包问题 poj 2187
    map的 简单用法
    判断线段是否在园内
    2-sat 问题
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4369359.html
Copyright © 2020-2023  润新知