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;
}

发布了110 篇原创文章 · 获赞 100 · 访问量 8027

猜你喜欢

转载自blog.csdn.net/dglyr/article/details/104848753
今日推荐