【jzoj1921】【二分】【2014.10.18普及组】自动匹配(auto.pas/cpp/c)

题目描述

奶牛贝里斯最近有了一部新手机,于是他经常发短信。但是他经常打错单词,因为手机屏幕太小而他的爪子太大了((⊙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 1000000 1000000, 1 < = N < = 1000 1<=N<=1000 1<=N<=1000,W<=30000,每个不完整的单词的长度不超过 1000 1000 1000

提示
【样例说明】

前缀是a的单词有aa,aaa,aab,ab,abc,ac,第4个是ab,ab在原字典库中是第3个。前缀是da的单词有daa,dab,dadba,第2个是dab,在原字典库中是第1个。没有第4个前缀是da的单词,所以输出-1。


解题思路

先给字典库内的单词排序,要记录原本在字典库的位置

对于每个查询的单词s,都二分一次,找到第一个出现前缀是s的单词位置

然后暴力往后枚举,找到第k个前缀是s的单词


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
using namespace std;
struct DT{
	int i;
	string s;
}a[30100];
int n,m,x,ans,l,r;
string s;
bool cmp(const DT&k,const DT&l){
	return (k.s<l.s);
}
int main(){
	freopen("auto.in","r",stdin);
	freopen("auto.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		cin>>a[i].s;
		a[i].i=i;//记录位置
	}
	sort(a+1,a+1+n,cmp);//排序
	for(int i=1;i<=m;i++){
		scanf("%d",&x);
		cin>>s;
		l=1,r=n;
		while(l<r){//二分
			int mid=(l+r)/2,t=0;
			for(int j=0;j<s.size();j++)
			     if(a[mid].s[j]!=s[j]){
			    	t=(int)(s[j])-(int)(a[mid].s[j]);
					break;
				 }
			if(t<=0)r=mid;
			   else l=mid+1;
		}
		ans=0;int j=r;
		while(j<=n&&ans<x){//暴力枚举
			for(int k=0;k<s.size();k++)
			    if(a[j].s[k]!=s[k]){
			    	ans--;
					j=n;break;
				}
			ans++;
			j++; 
		}
		--j;
		if(ans==x)printf("%d\n",a[j].i);
		   else printf("-1\n");
	}
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值