ACWING\1927. 自动补全
数据范围
1≤W≤30000
1≤N≤10000
1≤Ki≤W
输入样例:
10 3
dab
ba
ab
daa
aa
aaa
aab
abc
ac
dadba
4 a
2 da
4 da
输出样例:
3
1
-1
样例解释
a
的自动补全为 aa,aaa,aab,ab,abc,ac
,第四个为 ab
,在词典中排第 33 个。
da
的自动补全为 daa,dab,dadba
,第二个为 dab
,在词典中排第 11 个。
da
不存在第四个自动补全。
题解:排序 二分
-
将word进行排序,排序前用unordered_map记录每个单词的a下标
-
用lower_bound找到比目标值str大于等于的那一个位置,从此为第一开始找到第k个字符串goal_str
-
若找得到此字符串且字符串与str前缀是相同的,即输出unordered_map中记录的下标
#include <iostream>
#include <cstdio>
#include <cstring>
#include <unordered_map>
#include <algorithm>
using namespace std;
int my_low_boundint(string nums[],int n, string target) {
// 找到比n大于或等于的第一个元素
int l = 0, r = n, mid; // r = n的设计是为了
while (l < r) {
mid = l + ((r - l) >> 1); // 防止溢出的设计, 移位更快
if (nums[mid] < target) {
// 小于的时候向右移动,直到移动到大于等于target就不变了
l = mid + 1;
} else {
// 直至移动到和l相同的地方
r = mid;
}
}
return l;
}
int main(){
int w,n;
cin>>w>>n;
string word[w];
unordered_map<string,int> mp;
for(int i = 0;i<w;i++){
cin>>word[i];
mp[word[i]] = i+1;
}
sort(word,word+w);
while(n--){
int k;
string str;
cin>>k;
cin>>str;
int index = my_low_boundint(word, w, str);
if(k+index-1>=w) cout<<-1<<endl;
else{
string goal_str = word[k+index-1];
bool flag = 1;
for(int i = 0;i<str.length();i++){
if(str[i] != goal_str[i]){
flag = 0;
break;
}
}
if(flag){
cout<<mp[goal_str]<<endl;
}else{
cout<<-1<<endl;
}
}
}
return 0;
}