題意:給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;
}