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;
    }

     

  • 相关阅读:
    转载别人(ZZ)创建要素集
    CAD转化为Shp
    VBS学习
    3度带/6度带
    头文件学习,GEOTIFF
    arcmap vba 生成3维侧棱 以及 createfeature与createfeaturebuffer的区别
    另类
    幸福人生讲座(七):怎样引导孩子立志
    幸福人生讲座(四):孝道与仁爱是根本
    幸福人生讲座(二):人生怎样才能幸福?
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4751999.html
Copyright © 2011-2022 走看看