比赛 20170519 评测结果 WWWWWEEEEE
题目名称 子串 最终得分 0
用户昵称 Shirry 运行时间 0.415 s
代码语言 C++ 内存使用 0.97 MiB
提交时间 2017-05-19 21:58:45
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f3f
const int maxn=1010;
int next[maxn][26],fail[maxn],b[maxn],ind[256],cnt=1;
char s[27][27];
double r[26];
int n;
void insert(char *s){
	int len=strlen(s);
	int p=0;
	for(int i=0;i<len;i++){
		int c=ind[s[i]];
		if(!next[p][c]){
			b[cnt]=0;
			next[p][c]=++cnt;
		}
		p=next[p][c];
	}
	b[p]=1;
}
int head,tail,q[maxn];
void build(){
	head=tail=0;
	fail[0]=0;
	for(int i=0;i<26;i++){
		if(next[0][i]){
			fail[next[0][i]]=0;
			q[head++]=next[0][i];
		}
	}
	while(head<tail){
		int x=q[head++];
		for(int i=0;i<26;i++){
			if(!next[x][i]){
				next[x][i]=next[fail[x]][i];
				continue;
			}
			q[head++]=next[x][i];
			int p=fail[x];
			while(p&&!next[p][i])p=fail[p];
			fail[next[x][i]]=next[p][i];
			b[next[x][i]]|=b[fail[next[x][i]]];
		}
	}
}
double w[maxn][105]={0};
int vis[maxn][105]={0};
double getnum(int x,int l){
	if(!l)return 1.0;
	if(vis[x][l])return w[x][l];
	vis[x][l]=1;
	double& ans=w[x][l];
	ans=0.0;
	for(int i=0;i<n;i++)
		if(!b[next[x][i]])ans+=r[i]*getnum(next[x][i],l-1);
	return ans;
}
int work(){
	freopen("substrings.in","r",stdin);
	freopen("substrings.out","w",stdout);
	int t;
	scanf("%d",&t);
	for(int c=1;c<=t;c++){
		memset(vis,0,sizeof(vis));
		memset(w,0,sizeof(w));
		int k,l;
		char A[10];
		scanf("%d",&k);
		for(int i=0;i<k;i++)scanf("%s",s[i]);
		scanf("%d",&n);
		for(int i=0;i<n;i++)scanf("%s%lf",A,&r[i]),ind[A[0]]=i;
		for(int i=0;i<k;i++)insert(s[i]);
		build();
		scanf("%d",&l);
		double ans=getnum(0,l);
		printf("Case #%d: %.6lf\n",c,ans);
	}
	return 0;
}
int sh=work();
int main(){
	return 0;
}