题意:给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;
}