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 }
View Code

 

posted @ 2020-04-21 21:27  古比  阅读(147)  评论(0编辑  收藏  举报