zoukankan      html  css  js  c++  java
  • 【hdu2222】【poj2945】AC自动机入门题

    HDU2222 传送门

    题目分析

    裸题:注意构建自动机用的是模式串,思想和kmp很类似。

    code:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    
    const int N = 1e4 + 5, M = 55, L = 1e6 + 5;
    
    int T, n, tot, vst[N * M], vt;
    char t[M], s[L];
    
    struct node{
        int trans[30], fail;
        bool end;
        inline void clear(){
            fail = 0;
            memset(trans, 0, sizeof trans);
            end = false;
        }
    }trie[N * M];
    
    inline void insert(){
        int pos = 1, len = strlen(t + 1);
        for(int i = 1; i <= len; i++){
            if(!trie[pos].trans[t[i] - 'a' + 1])
                trie[trie[pos].trans[t[i] - 'a' + 1] = ++tot].clear();
            pos = trie[pos].trans[t[i] - 'a' + 1];
        }
        trie[pos].cnt++;
    }
    
    inline void buildFail(){
        static int qn, que[N * M];
        que[qn = 1] = 1;
        for(int ql = 1; ql <= qn; ql++){
            int u = que[ql];
            for(int i = 1; i <= 26; i++){
                int v = trie[u].fail;
                while(!trie[v].trans[i]) v = trie[v].fail;
                v = trie[v].trans[i];
                int w = trie[u].trans[i];
                if(w) trie[w].fail = v, que[++qn] = w;
                else trie[u].trans[i] = v;
            }
        }
    }
    
    int main(){
        scanf("%d", &T);
        for(int i = 1; i <= 26; i++) trie[0].trans[i] = 1;
        while(T--){
            ++vt;
            trie[tot = 1].clear();
            scanf("%d", &n);
            for(int i = 1; i <= n; i++){
                scanf("%s", t + 1);
                insert();
            }
            buildFail();
            scanf("%s", s + 1);
            int len = strlen(s + 1), tmp, now = 1, ans = 0;
            for(int i = 1; i <= len; i++){
                now = trie[now].trans[s[i] - 'a' + 1];
                tmp = now;
                while(tmp && vst[tmp] != vt){
                    vst[tmp] = vt;
                    ans += trie[tmp].cnt;
                    tmp = trie[tmp].fail;
                }
            }
            printf("%d
    ", ans);
        }
    }
    

    POJ2945

    传送门

    题目分析

    还是裸题,在字符串结束的地方打上标记

    code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    
    const int N = 2e4 + 5, M = 25;
    int n, m, ans[N];
    struct node{
    	node* trans[5];
    	int cnt;
    }trie[N * M], *tail = trie, *root;
    char s[M];
    
    inline node* newNode(){
    	node *x = tail++;
    	memset(x->trans, 0, sizeof x->trans);
    	x->cnt = 0;
    	return x;
    }
    
    inline int getVal(char t){
    	switch(t){
    		case 'A': return 1;
    		case 'C': return 2;
    		case 'G': return 3;
    		case 'T': return 4;
    	}
    }
    
    inline void insert(){
    	node *pos = root;
    	for(int i = 1; i <= m; i++){
    		int v = getVal(s[i]);
    		if(pos->trans[v] == NULL)
    			pos->trans[v] = newNode();
    		pos = pos->trans[v];
    	}
    	ans[pos->cnt]--;
    	ans[++pos->cnt]++;
    }
    
    int main(){
    	while(scanf("%d%d", &n, &m), n + m){
    		memset(ans, 0, sizeof ans);
    		tail = trie;
    		root = newNode();
    		for(int i = 1; i <= n; i++){
    			scanf("%s", s + 1);
    			insert();
    		}
    		for(int i = 1; i <= n; i++) printf("%d
    ", ans[i]);
    	}
    }
    
  • 相关阅读:
    20200925--矩阵加法(奥赛一本通P93 6 多维数组)
    20200924--图像相似度(奥赛一本通P92 5多维数组)
    20200923--计算鞍点(奥赛一本通P91 4)
    20200922--计算矩阵边缘元素之和(奥赛一本通P91 3二维数组)
    20200921--同行列对角线的格(奥赛一本通P89 2 二维数组)
    磨人的.net core 3.1(二) DataReader的问题
    磨人的.net core 3.1(一) CORS的问题
    Vue SSR问题:返回的js打包文件为HTML文件
    axios与.net core API实现文件下载
    .Net Core API中基于System.Threading.Timer的定时任务
  • 原文地址:https://www.cnblogs.com/CzYoL/p/7449822.html
Copyright © 2011-2022 走看看