zoukankan      html  css  js  c++  java
  • Detect the Virus

    题目大意:给你一些病毒的特征码,然后再给一些文本,判断每个文本有多少种病毒,不过给的字符串都是加密处理过的,给的每个字符串都有对应一个64以内的一个数(题目里面那个表就是),然后可以把这个64以内的这个数化成6位的二进制数,然后把这些二进制数每8位再化成一个字符,这就是原来的字符,比如 QA== ->编号0 1->二进制010000 000000->每8位变成一个字符 01000000 0000(后面这4个0就是那两个==,可以舍去)-> 64('@')。
     
    分析:因为是化成8位的二进制,2^8 = 256,不过因为有‘’这样的字符,所以无法使用char来搞,开一个int数组是个不错的选择,当然也得注意内存开销,申请内存的方式会MLE,实验得出结果开6W最好.....真是让人感觉很恶心,错了19次!!
     
    代码如下:
    ===============================================================================================================================
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<queue>
    using namespace std;
    
    const int MAXN = 10007;
    const int MAXM = 256;///2^8
    const int oo = 1e9+37;
    
    const char cb64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    int virus[MAXN], MumStr[MAXN];
    char s[MAXN];
    int password[MAXN*8];
    
    struct node
    {
        int Fail, next[MAXM];
        int leaf, num;
    
        void InIt()
        {
            Fail = leaf = num = 0;
            memset(next, 0, sizeof(next));
        }
    
    }trie[60000];
    int top;
    
    int TurnStr(char s[], int p[])
    {
        int i, j, k=0;
    
        for(i=0; s[i] && s[i] != '='; i++)
        {
            s[i] = strchr(cb64, s[i]) - cb64;
    
            for(j=5; j>=0; j--)
            {
                password[k+j] = s[i] % 2;
                s[i] /= 2;
            }
    
            k += 6;
        }
    
        int len = 0;
    
        for(i=j=0; i<k; i++)
        {
            j = j*2 + password[i];
    
            if((i+1) % 8 == 0)
            {
                p[len++] = j;
                j = 0;
            }
        }
    
        return len;
    }
    void Insert(int root, int N)
    {
        int p = root;
    
        for(int i=0; i<N; i++)
        {
            int k = virus[i];
    
            if(trie[p].next[k] == 0)
            {
                trie[p].next[k] = ++top;
                trie[top].InIt();
            }
            p = trie[p].next[k];
        }
    
        trie[p].leaf += 1;
    }
    void GetFail(int root)
    {
        int p = root, temp;
        queue<int> Q;
    
        trie[root].Fail = -1;
    
        for(int i=0; i<MAXM; i++)if(trie[p].next[i])
        {
            int k = trie[p].next[i];
    
            trie[k].Fail = root;
            Q.push(k);
        }
    
        while(Q.size())
        {
            p = Q.front();
            Q.pop();
    
            for(int i=0; i<MAXM; i++)if(trie[p].next[i])
            {
                int k = trie[p].next[i];
                temp = trie[p].Fail;
    
                while(temp != -1)
                {
                    if(trie[temp].next[i])
                    {
                        trie[k].Fail = trie[temp].next[i];
                        break;
                    }
    
                    temp = trie[temp].Fail;
                }
    
                if(temp == -1)
                    trie[k].Fail = root;
    
                Q.push(k);
            }
        }
    }
    int Query(int root, int N, int num)
    {
        int sum = 0;
        int p = root, temp;
    
        for(int i=0; i<N; i++)
        {
            int k = MumStr[i];
    
            while(!trie[p].next[k] && p!=root)
                p = trie[p].Fail;
    
            if(!trie[p].next[k])continue;
    
            temp = p = trie[p].next[k];
    
            while(temp != root && trie[temp].num != num)
            {
                if(trie[temp].leaf)
                    sum += 1;
                trie[temp].num = num;
                temp = trie[temp].Fail;
            }
        }
    
        return sum;
    }
    
    int main()
    {
        int N, M;
    
        while(scanf("%d", &N) != EOF)
        {
            int root = 0;
    
            trie[0].InIt();
            top = 0;
    
            for(int i=1; i<=N; i++)
            {
                scanf("%s", s);
                int len = TurnStr(s, virus);
    
                Insert(root, len);
            }
    
            GetFail(root);
            scanf("%d", &M);
    
            for(int i=1; i<=M; i++)
            {
                scanf("%s", s);
                int len = TurnStr(s, MumStr);
    
                printf("%d
    ", Query(root, len, i));
            }
            printf("
    ");
        }
    
        return 0;
    }

     

  • 相关阅读:
    centos7.6 安装与配置 MongoDB yum方式
    MongoDB 介绍
    centos 关闭selinux
    前端 HTML标签属性
    前端 HTML 标签嵌套规则
    前端 HTML 标签分类
    前端 HTML body标签相关内容 常用标签 表单标签 form里面的 input标签介绍
    前端 HTML body标签相关内容 常用标签 表单标签 form 表单控件分类
    前端 HTML form表单标签 select标签 option 下拉框
    POJ 1426
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4751999.html
Copyright © 2011-2022 走看看