zoj 3430 AC自动机

来源:互联网 发布:手机棋牌源码 编辑:程序博客网 时间:2024/06/05 16:11

题目链接:http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=16400


把输入的字符根据下表,转化成value数字,在转化成6位的二进制,载8个二进制一组划分,转化成0~255的数字(ASCII字符的十进制),然后就是AC自动机模版的事了。一个=表示转化得到的二进制末尾要去掉2个0

Value012345678910111213141516171819202122232425262728293031EncodingABCDEFGHIJKLMNOPQRSTUVWXYZabcdefValue3233343536373839404142434445464748495051525354555657585960616263Encodingghijklmnopqrstuvwxyz0123456789+/


3                        二进制                                              0~255YmFzZTY0       01100010 01100001 01110011 01100101 00110110 00110100     98 97 115 101 54 52dmlydXM=       01110110 01101001 01110010 01110101 01110011              118 105 114 117 115dDog           01110100 00111010 00100000                                116 58 321dGVzdDogdmlydXMu  01110100 01100101 01110011 01110100 00111010 00100000 01110110 01101001 01110010 01110101 01110011 00101110                                         116 101 115 116 58 32 118 105 114 117 115 461QA==       01000000              642QA==       01000000              64ICAgICAgICA=     00100000 00100000 00100000 00100000 00100000 00100000 00100000 00100000 32 32 32 32 32 32 32 32

尝试五种错误以后终于A了,转化部分写得有些糟


#include <queue>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 50010;struct Trie{    int next[N][260],fail[N],end[N],id[N];    int root,L;    int newnode()    {        for(int i = 0; i < 257; i++)            next[L][i] = -1;        id[L] = 0;        end[L++] = 0;        return L-1;    }    void init()    {        L = 0;        root = newnode();    }    void insert(int har[], int len)    {        int now = root;        for(int i = 1; i < len; i++)        {            if(next[now][har[i]] == -1)                next[now][har[i]] = newnode();            now = next[now][har[i]];        }        end[now]++;    }    void build()    {        queue<int>Q;        fail[root] = root;        for(int i = 0; i < 257; i++)        {            if(next[root][i] == -1)                next[root][i] = root;            else            {                fail[next[root][i]] = root;                Q.push(next[root][i]);             }        }        while(!Q.empty())        {            int now = Q.front();            Q.pop();            for(int i = 0; i < 257; i++)            {                if(next[now][i] == -1)                    next[now][i] = next[fail[now]][i];                else                {                    fail[next[now][i]] = next[fail[now]][i];                    Q.push(next[now][i]);                }            }        }    }    int query(int har[],int len,int ID)    {        int now = root;        int ans = 0;        for(int i = 1; i < len; i++)        {            now = next[now][har[i]];            int temp = now;            while(temp != root)            {                if(id[temp] != ID)                {                    ans += end[temp];                    id[temp] = ID;                }                temp = fail[temp];            }        }        return ans;    }};char buf[3000];int hub[18000];int har[3000];Trie ac;int change(){    int cnt = 0;    int len = strlen(buf);    int tmp;    int k = 0;    for(int i = 0; i < len; i++)    {        if(buf[i] >= 'A' && buf[i] <= 'Z')        {           tmp = buf[i] - 65;        }        else        {            if(buf[i] >= 'a' && buf[i] <= 'z')            {                tmp = buf[i] - 71;            }            else            {                if(buf[i] >= '0' && buf[i] <= '9')                    tmp = buf[i]+4;                else                {                    if(buf[i] == '+')                    {                        tmp = 62;                    }                    else                    {                        if(buf[i] == '/')                            tmp = 63;                    }                }            }        }        if(buf[i] == '=')            break;        int j = 6;        while(j--)        {            hub[k+j] = tmp%2;            tmp/=2;//转化成二进制        }        k += 6;        }    k = (k/8)*8;//base64只会添加2个或4个0    tmp = 0;    for(int i = 0; i <= k; i++)    {        if(i%8 == 0)        {            har[cnt++] = tmp;//插入从har[1]开始            tmp = hub[i];        }        else        {            tmp *= 2;            tmp += hub[i];        }    }    return cnt;}int main(int argc, char const *argv[]){    int n,m;    int len;    while(~scanf("%d",&n))    {        ac.init();        for(int i = 1; i <= n; i++)        {            scanf("%s",buf);            len = change();            ac.insert(har,len);        }        ac.build();        scanf("%d",&m);        for(int i = 1; i <= m; i++)        {            scanf("%s",buf);            len = change();            printf("%d\n",ac.query(har,len,i));        }        printf("\n");    }    return 0;}


0 0