Description
平平带着韵韵来到了游乐园,看到了n辆漂亮的遥控车,每辆车上都有一个唯一的名字name[i]。韵韵早就迫不及待地想玩名字是s的遥控车。可是韵韵毕竟还小,她想象的名字可能是一辆车名字的前缀(也就是说能确定一个i,使s是name[i]的前缀),这时她就能玩第i辆车;或者是一个无中生有的名字,即s不是任何一辆车名字的前缀,这时候她什么也不能玩。
你需要完成下面的任务:
1.韵韵想了m个她想要的名字,请告诉她能玩多少次。
2.由于管理员粗心的操作,导致每辆车的摆放位置都可能出现微小的差错,原来第i辆车现在的位置可能是i-1、i、i+1中的任意一个(第1辆车的位置不可能是0,第n辆车的位置不可能是n+1)。请你计算出共有多少种可能的排列。
注:数据保证当s是name[i]的前缀时,i是唯一确定的。一辆车可以玩多次。
Input
第一行是2个正整数n、m。
接下来n行,每行1个字符串name[i],表示第i辆车的名字。
接下来m行,每行1个字符串s,表示韵韵想要的名字。
Output
第一行输出韵韵能玩的次数。
第二行输出共有多少种可能的排列。
Sample Input
4 4
Abcd
DeF
AAa
aBccc
Ab
AA
AbC
aBcc
Sample Output
3
5
Data Constraint
Hint
【数据规模和约定】
对于题目涉及到的字符串严格区分大小写,且长度小于255。
对于20%的数据 n≤10,m≤10;
对于40%的数据 n≤1000,m≤1000;
对于100%的数据 n≤10000,m≤10000。
思路
一开始想用trie,发现会MLE
所以用二分找出字符串在判断一下即可
第二问就是斐波那契数列,只不过要高精度
代码
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#define N 10077
using namespace std;
string s[N];
int a[N],b[N],p[N],la=1,lb=1;
int main()
{
int n,m,ans=0;
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++) cin>>s[i];
sort(s+1,s+n+1);
for(int i=1; i<=m; i++)
{
string c;
cin>>c;
int l=1,r=n;
while(l<=r)
{
int mid=(l+r)/2;
if(s[mid]<c) l=mid+1;
else r=mid-1;
}
if(s[l].find(c,0)==0) ans++;
}
printf("%d\n",ans);
if(n<=2)
{
printf("%d",n);
return 0;
}
a[1]=1; b[1]=2;
for(int i=3; i<=n; i++)
{
memset(p,0,sizeof(p));
int lc=max(la,lb);
for(int j=1; j<=lc; j++)
{
p[j]+=a[j]+b[j];
p[j+1]+=p[j]/10;
p[j]%=10;
}
if(p[lc+1]) lc++;
la=lb; for(int j=1; j<=la; j++) a[j]=b[j];
lb=lc; for(int j=1; j<=lb; j++) b[j]=p[j];
}
for(int i=lb; i>=1; i--) printf("%d",b[i]);
return 0;
}