动规优化里面也要大量使用二分查找,我觉得这道题对二分查找考察的很好
我的做法是在字典序中查找不小于输入字串的最小字串,对于它及它之后的字串判断是否以输入字串为前缀。
由于题目中说有重复的字串,我给重复的字串加了个标记。
//By YY_More
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node{
char st[30];
};
node f[10010];
bool nok[10010];
int n,k,p,q;
char str[30];
bool com(node x,node y){
return strcmp(x.st,y.st)<0;
};
int search(char *s){
int L=1,R=n,mid;
while (L<R){
mid=(L+R)/2;
if (strcmp(f[mid].st,s)<0) L=mid+1;
else R=mid;
}
if (L>R||strstr(f[L].st,s)!=f[L].st) return -1;
else return L;
};
int main(){
scanf("%d",&n);
getchar();
for (int i=1;i<=n;i++) gets(f[i].st);
sort(f+1,f+n+1,com);
for (int i=2;i<=n;i++)
if (strcmp(f[i].st,f[i-1].st)==0) nok[i]=true;//处理重复的字串
scanf("%d",&q);getchar();
for (int i=1;i<=q;i++){
gets(str);
p=search(str);
if (p==-1) printf("%s",str);
else {
k=0;
while ((strstr(f[p].st,str)==f[p].st)&&(k<8)){
if (!nok[p]) {k++;if (k>1) printf(" %s",f[p].st);
else printf("%s",f[p].st);}
p++;
}
}
printf("\n");
}
}