zoukankan      html  css  js  c++  java
  • CF #Manthan, Codefest 16 C. Spy Syndrome 2 Trie

    题目链接:http://codeforces.com/problemset/problem/633/C

    大意就是给个字典和一个字符串,求一个用字典中的单词恰好构成字符串的匹配。

    比赛的时候是用AC自动机写的,就是对于trie中每一个节点,判断是否为终结点,以及当前字符所在位置p减去trie中这个节点的深度也即某一单词的长度l,判断dp[p-l]是否可以被构成,可以的话直接break并且标记当前dp值。

    赛后想了想,其实直接一个trie就行了,每个单词才1000的长度,又想起来我去年给人讲过类似的问题,当时我自己非常清楚这种单词构成用个简单的tire来搞就行。怎么比赛的时候就写了个AC自动机了呢。

     1 #include <iostream>
     2 #include <vector>
     3 #include <algorithm>
     4 #include <string>
     5 #include <string.h>
     6 #include <stdio.h>
     7 #include <math.h>
     8 #include <stdlib.h>
     9 #include <queue>
    10 #include <stack>
    11 #include <map>
    12 #include <set>
    13 #include <ctime>
    14 #include <numeric>
    15 #include <cassert>
    16 
    17 using namespace std;
    18 const int N=100001;
    19 string dic[N];
    20 char str[N],pat[N];
    21 int mark[N];
    22 const int CHARSET=26,BASE='a',MAX_NODE=1000001;
    23 struct Trie {
    24     int tot,root,child[MAX_NODE][CHARSET];
    25     int flag[MAX_NODE];
    26     Trie(){
    27         init();
    28     }
    29     void init(){
    30         root=newNode();
    31     }
    32     int newNode() {
    33         ++tot;
    34         memset(child[tot],0,sizeof(child[tot]));
    35         flag[tot]=0;
    36         return tot;
    37     }
    38     void insert(const char *str,int id){
    39         int *cur=&root;
    40         for (const char *p=str;*p;++p){
    41             cur=&child[*cur][*p-BASE];
    42             if (*cur==0)
    43                 *cur=newNode();
    44         }
    45         flag[*cur]=id;
    46     }
    47     void query(int x){
    48         int *cur=&root;
    49         for (int i=x;i>=1;i--){
    50             char ch=str[i];
    51             cur=&child[*cur][ch-BASE];
    52             if ((*cur)==0) break;
    53             if (flag[*cur]&&mark[i-1]!=-1){
    54                 mark[x]=flag[*cur];
    55                 break;
    56             }
    57         }
    58     }
    59 }trie;
    60 int main () {
    61     int n;
    62     scanf("%d",&n);
    63     scanf("%s",str+1);
    64     int m;
    65     scanf("%d",&m);
    66     for (int i=1;i<=m;i++) {
    67         scanf("%s",pat);
    68         dic[i]=string(pat);
    69         int len=dic[i].length();
    70         for (int j=0;j<=len;j++)
    71             if (pat[j]>='A'&&pat[j]<='Z')
    72                 pat[j]+='a'-'A';
    73         trie.insert(pat,i);
    74     }
    75     memset(mark,-1,sizeof mark);
    76     mark[0]=0;
    77     for (int i=1;i<=n;i++){
    78         trie.query(i);
    79     }
    80     vector<int> ret;
    81     int now=n;
    82     while (now>0) {
    83         ret.push_back(mark[now]);
    84         now-=dic[mark[now]].length();
    85     }
    86     for (int i=(int)ret.size()-1;i>=0;i--) {
    87         printf("%s ",dic[ret[i]].c_str());
    88     }
    89     return 0;
    90 }
    View Code
  • 相关阅读:
    粒子贴片渲染的边缘柔化。
    灯塔,大海,大风。(一)
    紫色乐趣。
    灯塔,大海,大风。(三)
    Maya中实现快速伪SPH粒子。
    灯塔,大海,大风。(二)
    灯塔,大海,大风。Final.
    2D流体火焰,低精度测试。
    灯塔,大海,大风。(四)
    2010年冬视觉特效作品集。
  • 原文地址:https://www.cnblogs.com/micrari/p/5229383.html
Copyright © 2011-2022 走看看