程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> BZOJ 1212 HNOI 2004 L語言 Trie樹

BZOJ 1212 HNOI 2004 L語言 Trie樹

編輯:C++入門知識

BZOJ 1212 HNOI 2004 L語言 Trie樹


題目大意:給出一些單詞,和一些句子,當且僅當句子可以分割成的子串都可以被詞典翻譯,就說明這個子串是可以被翻譯的。求最長的可以被翻譯的前綴長度。


思路:利用Trie樹來刷數組,能夠刷到的最長的地方就是這個串最長可以翻譯到的地方。

PS:在BZOJ上Trie居然比AC自動機快,我的渣代碼都刷到第一篇了。。。


CODE:

#include 
#include 
#include 
#include 
using namespace std;
 
struct Trie{
    Trie *son[27];
    bool end;
     
    Trie() {
        memset(son,NULL,sizeof(son));
        end = false;
    }
}*root = new Trie();
 
int words,cnt;
char s[1 << 20|100],temp[20];
bool f[1 << 20|100];
 
inline void Insert(char *s)
{
    Trie *now = root;
    while(*s != '\0') {
        if(now->son[*s - 'a'] == NULL)
            now->son[*s - 'a'] = new Trie();
        now = now->son[*s - 'a'];
        ++s;
    }
    now->end = true;
}
 
inline void Ask(char *s,int i)
{
    Trie *now = root;
    int t = 0;
    while(*s != '\0') {
        if(now->son[*s - 'a'] == NULL)
            return ;
        now = now->son[*s - 'a'];
        ++s;
        ++t;
        if(now->end) f[i + t] = true;
    }
    if(now->end) f[i + t] = true;
}
 
inline int Work()
{
    memset(f,false,sizeof(f));
    f[0] = true;
    int re = 0,length = strlen(s + 1);
    for(int i = 0; i <= length; ++i) {
        if(!f[i])   continue;
        re = i;
        Ask(s + i + 1,i);
    }
    return re;
}
 
int main()
{
    cin >> words >> cnt;
    for(int i = 1; i <= words; ++i) {
        scanf("%s",temp);
        Insert(temp);
    }
    for(int i = 1; i <= cnt; ++i) {
        scanf("%s",s + 1);
        printf("%d\n",Work());
    }
    return 0;
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved