題目鏈接:點擊打開鏈接
思路:
因爲單詞最長15, 我們把每個單詞不同長度的前綴存起來, 排序之後二分即可, 複雜度O(nlogn)
細節參見代碼:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <ctime>
#include <bitset>
#include <cstdlib>
#include <cmath>
#include <set>
#include <list>
#include <deque>
#include <map>
#include <queue>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
typedef long double ld;
const double eps = 1e-6;
const double PI = acos(-1);
const int mod = 1000000000 + 7;
const int INF = 0x3f3f3f3f;
// & 0x7FFFFFFF
const int seed = 131;
const ll INF64 = ll(1e18);
const int maxn = 1e5 + 10;
int T,n,m,L[maxn];
struct node {
char s[16], name[16];
int p;
node(char _s[], char str[], int _p) {
strcpy(s, _s);
strcpy(name, str);
p = _p;
}
node() {}
bool operator < (const node& rhs) const {
int cur = strcmp(name, rhs.name);
if(cur == 0) {
if(p == rhs.p) {
int cmp = strcmp(s, rhs.s);
return cmp < 0;
}
else return p > rhs.p;
}
else return cur < 0;
}
};
node a[maxn];
char op[19];
vector<node> b[17];
int main() {
while(~scanf("%d", &n)) {
int maxlen = 0;
for(int i = 1; i <= n; i++) {
scanf("%s%d", a[i].s, &a[i].p);
L[i] = strlen(a[i].s);
maxlen = max(maxlen, L[i]);
}
for(int i = 1; i <= maxlen; i++) b[i].clear();
for(int i = 1; i <= n; i++) {
for(int j = 0; j < L[i]; j++) {
op[j] = a[i].s[j];
op[j+1] = 0;
b[j+1].push_back(node(a[i].s, op, a[i].p));
}
}
for(int i = 1; i <= maxlen; i++) sort(b[i].begin(), b[i].end());
scanf("%d", &m);
while(m--) {
scanf("%s", op);
int len = strlen(op);
int pos = lower_bound(b[len].begin(), b[len].end(), node(op, op, INF)) - b[len].begin();
int lenth = b[len].size();
for(int i = pos; i < lenth; i++) {
if(strcmp(b[len][i].name, op) != 0) break;
printf("%s\n", b[len][i].s);
if(i - pos + 1 >= 10) break;
}
if(m) printf("\n");
}
}
return 0;
}