題意跟簡單,就是模擬輸入法,統計前綴的頻率時要把相同前綴的單詞頻率相加,所以只能採用離線算法,預先把詞頻統計出來,這個用字典樹統計,同樣輸入數字按鍵時也要在字典樹上查找,爲此建了兩顆字典樹,一顆統計詞頻,一顆查詢數字鍵。
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 111;
const int MAXM = 1010;
typedef struct charNode{
string str;
int cnt;
charNode(){
cnt = 0;
str = "";
}
charNode(string str, int cnt){
this->cnt = cnt;
this->str = str;
}
bool operator < (const charNode &A) const{
return cnt > A.cnt;
}
}charNode;
typedef struct Node{
int issort;
vector<charNode>target;
Node *child[8];
Node(){
issort = 0;
target.clear();
for(int i = 0; i < 8; i ++)
child[i] = NULL;
}
}Node;
typedef struct Word{
int cnt;
Word *child[26];
Word(){
cnt = 0;
for(int i = 0; i < 26; i ++)
child[i] = NULL;
}
}Word;
Node *rt;
Word *charrt;
inline int hash(char c){
if(c >= 'a' && c <= 'c') return 0;
if(c >= 'd' && c <= 'f') return 1;
if(c >= 'g' && c <= 'i') return 2;
if(c >= 'j' && c <= 'l') return 3;
if(c >= 'm' && c <= 'o') return 4;
if(c >= 'p' && c <= 's') return 5;
if(c >= 't' && c <= 'v') return 6;
if(c >= 'w' && c <= 'z') return 7;
}
inline void buildTrieChar(char str[], int cnt){
Word *tmp = charrt;
while(str[0]){
int idx = str[0]-'a';
if(tmp->child[idx] == NULL) tmp->child[idx] = new Word();
tmp = tmp->child[idx];
tmp->cnt += cnt;
str++;
}
}
inline int cntTime(char *low, char *high){
Word *tmp = charrt;
for(char *i = low; i <= high; i ++){
int idx = *i - 'a';
tmp = tmp->child[idx];
}
return tmp->cnt;
}
inline void buildTrieNum(char str[]){
Node *tmp = rt;
int len = strlen(str);
for(int i = 0; i < len; i ++){
int idx = hash(str[i]);
if(tmp->child[idx] == NULL) tmp->child[idx] = new Node();
Node *p =tmp->child[idx];
int cnt = cntTime(str, str+i);
p->target.push_back(charNode(string(str, 0, i+1), cnt));
tmp = p;
}
}
inline void input(char str[]){
int i;
Node *tmp = rt;
int len = strlen(str);
for(i = 0; i < len-1; i ++){
int idx = str[i] - '2';
if(tmp->child[idx]){
tmp = tmp->child[idx];
if(!tmp->issort){
sort(tmp->target.begin(), tmp->target.end());
tmp->issort = 1;
}
int cnt = tmp->target.at(0).cnt;
cout << tmp->target.at(0).str << endl;
}else break;
}
for(int j = i; j < len - 1; j ++) printf("MANUALLY\n");
}
int main(){
char str[MAXM][MAXN];
int t, n, m, cnt;
#ifndef ONLINE_JUDGE
freopen("in.cpp", "r", stdin);
#endif
scanf("%d", &t);
for(int i = 1; i <= t; i ++){
rt = new Node();
charrt = new Word();
printf("Scenario #%d:\n", i);
scanf("%d", &n);
for(int i = 0; i < n; i ++){
scanf("%s%d", str[i], &cnt);
buildTrieChar(str[i], cnt);
}
for(int i = 0; i < n; i ++) buildTrieNum(str[i]);
scanf("%d", &m);
for(int i = 0; i < m; i ++){
scanf("%s",str[i]);
input(str[i]);
printf("\n");
}
printf("\n");
}
return 0;
}