NDK 1252 不怕噩梦

问题描述:

 蚊子最近经常做噩梦,然后就会被吓醒。这可不好。。疯子一直在发愁,然后突然有一天,  他发现蚊子其实就是害怕某些事。如果那些事出现在她的梦里,就会害怕。我们可以假定那  个害怕的事其实是一个字符串。而她做的梦其实也是一个字符串。 
 她可以一个晚上一直做梦,所以梦这个字符串会很长,如果其中包含了她所害怕的事情,那  么她这天晚上就会害怕。当然一个害怕的事也可能在这天晚上被她梦到很多遍,当然每个晚  上也可能有很多种害怕的事都被梦到。 
 每个害怕的事都有一定的权值。而这天晚上如果梦到了某件事,那么这件事所产生的黑暗效  果等于这件事的权值乘以这个害怕的事在梦字符串里的开始位置。如果同样的事梦到了很多  遍,那么就重复上面的操作很多遍。当天晚上的黑暗效果总和等于当天所有害怕的事产生的  黑暗效果累加到一起。现在疯子想知道蚊子这些天来噩梦的黑暗效果总和是多少。 

数据输入:

 第1行两个整数N,M代表一共有N天梦和M个害怕的事。 
 第2行到第M+1行。每行一个字符串ti,代表第I个害怕的事 
 第M+2行到第2M+2行。每行一个整数ai.代表第I个害怕的事权值 
 第2M+3行到第N+2M+3行。每行一个字符串si,代表第I天的梦。

结果输出:

 SUM 
 SUM=N天里黑暗效果的总和。 
 我们保证每天的黑暗效果都小于maxlongint; 

样例:

 2 2

 abc

 def

 1

 2

 abcdef

 defabc

 15

核心思想:

 模拟一秒的话能拿70,可以用kmp的,正好练练手

var
 a,s:array[0..210]of string;
 p,d:array[0..256]of longint;
 i,j,sum,n,m:longint;
procedure kmp(l,x:longint);
var
 i,j,k:longint;
begin
 fillchar(p,sizeof(p),0);
 j:=0;
 fori:=2 to l do
 begin
  while (j>0)and(a[x][j+1]<>a[x][i]) do j:=p[j];
   ifa[x][j+1]=a[x][i] then inc(j);
  p[i]:=j;
 end;
 fork:=1 to n do
 begin
  j:=0;
  for i:=1 to length(s[k]) do
   begin
    while (j>0)and(a[x][j+1]<>s[k][i]) do j:=p[j];
    if a[x][j+1]=s[k][i] then inc(j);
    if j=l then
     begin
      sum:=sum+(i-l+1)*d[x];
      j:=p[j];
     end;
   end;
 end;
end;
begin
 assign(input,'p1252.in');reset(input);
 assign(output,'p1252.out');rewrite(output);
 readln(n,m);
 sum:=0;
 fori:=1 to m do readln(a[i]);
 fori:=1 to m do readln(d[i]);
 fori:=1 to n do readln(s[i]);
 fori:=1 to m do
 kmp(length(a[i]),i);
 writeln(sum);
 close(input);close(output);
end.
题目来源:NDK 1252

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章