URAL-1542 Autocompletion (字典序)

Autocompletion
Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Description

The Japanese are infinitely in love with machinery that surrounds them. They follow closely all technical innovations and try to use the most modern and clever of them. Den and Sergey have an ingenious plan: they want to create a text editor that will win the Japanese over. The most important feature of the editor will be the autocompletion function. If a user has typed first several letters of a word, then the editor will automatically suggest the most probable endings. 
Den and Sergey have collected a lot of Japanese texts. For each Japanese word they counted the number of times it was found in the texts. For the first several letters entered by a user, the editor must show no more than ten words starting with these letters that are most commonly used. These words will be arranged in the order of decreasing encounter frequencies. 
Help Sergey and Den to turn over the market of text editors. 

Input

The first line contains the number of words found in the texts N (1 ≤  N ≤ 10 5). Each of the following N lines contains a word wi and an integer ni separated with a space, where wi is a nonempty sequence of lowercase Latin letters no longer than 15 symbols, and ni (1 ≤ ni ≤ 10 6) is the number of times this word is encountered in the texts. The ( N + 2)th line contains a number M (1 ≤  M ≤ 15000). In each of the next M lines there is a word ui (a nonempty sequence of lowercase Latin letters no longer than 15 symbols), which is the beginning of a word entered by a user. 

Output

For each of the M lines, output the most commonly used Japanese words starting with ui in the order of decreasing encounter frequency. If some words have equal frequencies, sort them lexicographically. If there are more than ten different words starting with the given sequence, output the first ten of them. The lists of words for each ui must be separated by an empty line. 

Sample Input

input output
5
kare 10
kanojo 20
karetachi 1
korosu 7
sakura 3
3
k
ka
kar
kanojo
kare
korosu
karetachi

kanojo
kare
karetachi

kare
karetachi

題意:給n個單詞,並給出詞頻,按照詞頻爲第一優先級,字典序爲第二優先級排序。之後m個詢問,每次詢問給出前綴,將前10個前綴匹配的單詞輸出,按照排序後的順序。

解法:神奇的解法,先按詢問建樹,之後將排序後的單詞按順序查找,在結點處查詢時記錄查詢的id和該結點被查詢的次數,超過10次則跳過。最後統一輸出。

自己碼的莫名wa了,很奇怪,代碼十分相似還是wa,最後貼別人代碼過的。

#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;
#define INF 0x3f3f3f3f
const int N=100005;
const int mod=1e9+7;

typedef struct Trie{
    Trie *next[26];
    bool v;
    vector<int> ans;
}Trie;

struct word{
    char w[16];
    int time;
}s[N];

Trie *root=(Trie *)malloc(sizeof(Trie));

void insert(char *str){
    int len=strlen(str);
    Trie *p = root,*q;
    for (int i=0; i<len; i++) {
        int id=str[i]-'a';
        if (p->next[id]==NULL) {
            q=(Trie *)malloc(sizeof(Trie));
            q->v=0;
            for (int j=0; j<26; j++)
                q->next[j]=NULL;
            p->next[id]=q;
        }
        p=p->next[id];
    }
    p->v=true;
}

void output(char *str) {
    Trie *p=root;
    int len=strlen(str);
    for (int i=0; i<len; i++) {
        int id=str[i]-'a';
        p=p->next[id];
    }
    for (int i=0; i<p->ans.size(); i++) {
        printf("%s\n",s[p->ans[i]].w);
    }
}

int find(char *str,int id){
    int len=strlen(str);
    Trie *p = root;
    for (int i=0; i<len; i++) {
        int id=str[i]-'a';
        p=p->next[id];
        if (p==NULL) return 0;
        if (p->ans.size()>=10) {
            continue;
        }
        p->ans.push_back(id);
    }
    return p->v;
}

void del(Trie *root){
    for (int i=0; i<26; i++) {
        if (root->next[i]!=NULL) {
            del(root->next[i]);
        }
    }
    free(root);
}


bool cmp(word a, word b) {
    if (a.time!=b.time) {
        return a.time>b.time;
    }
    return strcmp(a.w, b.w)<0;
}

char que[15005][15];

int main() {
    int n,m;
    cin>>n;
    for (int i=0; i<26; i++) {
        root->next[i]=NULL;
    }
    root->v=0;
    for (int i=0; i<n; i++) {
        scanf("%s %d",s[i].w,&s[i].time);
    }
    sort(s, s+n, cmp);
    cin>>m;
    for (int i=0; i<m; i++) {
        scanf("%s",que[i]);
        insert(que[i]);
    }
    for (int i=0; i<n; i++) {
        find(s[i].w, i);
    }
    for (int i=0; i<m; i++) {
        if (i) puts("");
        output(que[i]);
    }
    del(root);
    return 0;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章