hihocoder 1107 Shortest Proper Prefix

1107 : Shortest Proper Prefix

時間限制:10000ms
單點時限:1000ms
內存限制:512MB
描述

Query auto-completion(QAC) is widely used in many search applications. The basic idea is that when you type some string s in the search box several high-frequency queries which have s as a prefix are suggested. We say string s1 has string s2 as a prefix if and only if the first |s2| characters of s1 are the same as s2 where |s2| is the length of s2.

These days Little Hi has been working on a way to improve the QAC performance. He collected N high-frequency queries. We say a string s is a proper prefix if there are no more than 5 collected queries have s as a prefix. A string s is a shortest proper prefix if s is a proper prefix and all the prefixes of s(except for s itself) are not proper prefixes. Little Hi wants to know the number of shortest proper prefixes given N collected queries.

Hint: the 4 shortest proper prefixes for Sample Input are “ab”, “bb”, “bc” and “be”. Empty string “” is not counted as a proper prefix even if N <= 5.

輸入
The first line contains N(N <= 10000), the number of collected queries.

The following N lines each contain a query.

Each query contains only lowercase letters ‘a’-‘z’.

The total length of all queries are no more than 2000000.

Input may contain identical queries. Count them separately when you calculate the number of queries that have some string as a prefix.

輸出
Output the number of shortest proper prefixes.

樣例輸入
12
a
ab
abc
abcde
abcde
abcba
bcd
bcde
bcbbd
bcac
bee
bbb
樣例輸出
4

//trie樹

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <algorithm>
#include <map>
#include <vector>

using namespace std;

struct trie{ //建立一顆字典樹
    char key;
    int num;
    trie *next[26];
    trie(){
        num = 0;
        for(int i = 0; i < 26; i++) next[i] = NULL;
    }

};

trie root;//創建根節點

void ins(string s) { //插入新單詞
    trie *head = &root;

    for(int i = 0; i < s.size(); i++) {
        int k = s[i] - 'a';

        if(head->next[k] == NULL) {
            trie *node = new trie;
            node->key = s[i];
            head->next[k] = node;

        }
        head = head->next[k];
        head->num++;
    }

}

int ans = 0; //題目所述proper prefix的個數
map<trie *,int>k; //建立一個映射,後面會用到

void bia(trie *head) {//遍歷字典樹

         for(int i = 0; i < 26; i++) {
            int flag = 0;

            if(head->num <= 5 &&head != &root) {//滿足條件的節點
                    if(k[head] != 1)//若此節點之前未統計過
                    ans++;
                    flag = 1; //標記,此節點後面的分支都不用再遍歷了
                    k[head] = 1;//已統計過的節點,標記一下
            }

            //不是最後一個節點且前面還沒遇到滿足條件的節點
             if(head->next[i] != NULL && !flag)        
               bia(head->next[i]);//遞歸

        }

}

int main(){

    string s;
    int n,m;
    cin >> n;
    while(n--) {
        cin >> s;
        ins(s);
    }

    trie *head = &root;

    bia(head);
    cout << ans;
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章