題目描述
奶牛貝里斯最近有了一部新手機,於是他經常發短信。但是他經常打錯單詞,因爲手機屏幕太小而他的爪子太大了((⊙o⊙))。農夫約翰決定幫助貝里斯來開發一個app應用,使得可以從一個不完整的單詞猜想整個單詞。
App應用是由W個單詞組成的,每個單詞都是由’a’…’z’組成的,這些單詞總的長度不超過1000000。現在,總共有N個不完整的單詞,每個單詞的度不超過1000。對於第i個不完整的單詞S_i,app應用要計算出在單詞庫中,按字典序排列的第K_i個前綴是S_i的單詞。注意,自己也是自己的前綴。
輸入
第一行是兩個正整數W和N。
接下來W行,每行一個字典庫裏的單詞。
接下里N行,每行一個K_i和其對應的不完整的單詞S_i。
輸出
輸出包括N行,對於第i行,輸出在字典庫中按字典序排列的滿足前綴是S_i的第K_i個單詞在原字典庫中的位置。如果沒有足夠的單詞,就輸出-1。
樣例輸入
10 3
dab
ba
ab
daa
aa
aaa
aab
abc
ac
dadba
4 a
2 da
4 da
樣例輸出
3
1
-1
數據範圍限制
字典庫中單詞的總長度不超過1000000,1<=N<=1000,每個不完整的單詞的長度不超過1000。
W<=30000。
提示
【樣例說明】
前綴是a的單詞有aa,aaa,aab,ab,abc,ac,第4個是ab,ab在原字典庫中是第3個。前綴是da的單詞有daa,dab,dadba,第2個是dab,在原字典庫中是第1個。沒有第4個前綴是da的單詞,所以輸出-1。
分析
這題一開始打暴力只有10分,自己感覺沒什麼錯。然後去膜beginend大佬,卻直接被鄙視。。。
隨後發現要二分的亞子,還好c++有爽快的lower_bound。
先結構體記錄數組和排名,然後字典序快排。拿一個數組複製一下排好序的數組。然後對於每個c(前綴),先二分找到它第一次出現的位置,然後加上x(表示第幾個這樣的前綴)。因爲同樣的前綴排序的位置肯定是在一起的。如果有這樣一個字符串就輸出,沒有就是-1。
上代碼
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int w,n,x;
string c,ff[30001];
struct node
{
int p;string st;
}a[30001];//結構體不說
int cmp(node x,node y)
{
return x.st<y.st;//以st爲關鍵字排序
}
int main()
{
freopen("auto.in","r",stdin);
freopen("auto.out","w",stdout);
cin>>w>>n;
for(register int i=1;i<=w;i++)
{
cin>>a[i].st;
a[i].p=i;//記錄排名
}
sort(a,a+w+1,cmp);
for(int i=1;i<=w;i++)
{
ff[i]=a[i].st;//複製數組
}
for(int i=1;i<=n;i++)
{
cin>>x;cin>>c;
int l=lower_bound(ff+1,ff+w+1,c)-ff;//在字典裏二分找c
l=l+x-1;//加上x個位置
if(l>w)
{
cout<<-1<<endl;
continue;
}
if(!ff[l].find(c,0))//在第x個串查找有沒有
{
cout<<a[l].p<<endl;
}
else cout<<-1<<endl;
}
fclose(stdin);
fclose(stdout);
return 0;
}