2020寒假【gmoj1921】【auto自動匹配】【二分】【字符串】

題目描述

奶牛貝里斯最近有了一部新手機,於是他經常發短信。但是他經常打錯單詞,因爲手機屏幕太小而他的爪子太大了((⊙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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章