P2237 字符串方面的二分
题意:给出w个单词,给出m个询问
每个询问给出一个数k,一个前缀字符串pre
问,以pre为前缀的单词,按字典序排序排第k个的序号是多少?
思路:我们将所有单词按字典序排序
询问的时候,我们按pre二分查找(这里用lower_bound)找到第一个位置,
然后+k-1,就是按字典序排序后的第k个位置
但是,这第k个位置有可能不是我们想要的以pre为前缀的字符串
我们需要特判一下
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=3e4+10; 4 pair<string,int>a[maxn]; 5 bool match(string x,string y) 6 { 7 if(y.length()>x.length()) return 0; 8 return x.substr(0,y.size())==y; 9 } 10 int main() 11 { 12 int w,m; 13 scanf("%d%d",&w,&m); 14 for(int i=0;i<w;i++){ 15 cin>>a[i].first; 16 a[i].second=i; 17 } 18 sort(a,a+w); 19 for(int i=1;i<=m;i++){ 20 int k; 21 string pre; 22 cin>>k>>pre; 23 int pos=k-1+lower_bound(a,a+w,make_pair(pre,0))-a; 24 if (pos>=w || !match(a[pos].first,pre)){ 25 printf("-1\n"); 26 continue; 27 } 28 cout<<a[pos].second+1<<'\n'; 29 } 30 return 0; 31 }