【CSP-S膜你考】不怕噩梦 (模拟)
不怕噩梦
题面
蚊子最近经常做噩梦,然后就会被吓醒。这可不好。。
疯子一直在发愁,然后突然有一天,他发现蚊子其实就是害怕某些事。
如果那些事出现在她的梦里,就会害怕。
我们可以假定那个害怕的事其实是一个字符串。而她做的梦其实也是一个字符串。
她可以一个晚上一直做梦,所以梦这个字符串会很长,如果其中包含了她所害怕的事情,那么她这天晚上就会害怕。
当然一个害怕的事也可能在这天晚上被她梦到很多遍,当然每个晚上也可能有很多种害怕的事都被梦到。
每个害怕的事都有一定的权值。
而这天晚上如果梦到了某件事,那么这件事所产生的黑暗效果等于这件事的权值乘以这个害怕的事在梦字符串里的开始位置。
如果同样的事梦到了很多遍,那么就重复上面的操作很多遍。
当天晚上的黑暗效果总和等于当天所有害怕的事产生的黑暗效果累加到一起。
现在疯子想知道蚊子这些天来噩梦的黑暗效果总和是多少。
输入格式
第\(1\)行两个整数\(N,M\)代表一共有\(N\)天梦和\(M\)个害怕的事。
第\(2\)行到第\(M+1\)行。每行一个字符串\(t_i\),代表第\(i\)个害怕的事
第\(M+2\)行到第\(2M+2\)行。每行一个整数\(a_i\).代表第\(i\)个害怕的事权值
第\(2M+3\)行到第\(N+2M+3\)行。每行一个字符串\(s_i\),代表第\(i\)天的梦。
输出格式
$SUM $
\(SUM=N\)天里黑暗效果的总和。
我们保证每天的黑暗效果都小于\(\texttt{maxlongint}\);
样例
\(\texttt{input\#1}\)
2 2
abc
def
1
2
abcdef
defabc
\(\texttt{output\#1}\)
15
数据范围与提示
【样例解释】
\(1 * 1 + 2 * 4 + 1 * 4 + 2 * 1 = 15\)
对于数据的把握和时间复杂度的估计是成败的关键。
如果出现一个梦是:ab
而害怕的事有a,b,ab,那么a,b,ab都需要参与计算..
【数据范围】
对于$30 % $的数据
\(N,M \leqslant 50\)
对于所有的数据
\(N<=200.M<=200. length(s_i)<=200.length(t_i)<=200.a_i<=10.\)
题解
str1.find(str2,qwq)是从str1的qwq位置开始找str2找到的话返回str2在str1中的从qwq位置开始第一次出现的位置。模拟即可。
\(Code\)
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
typedef long long ll;
ll ans,n,m;
std::string sss[201];
struct aaa {
std::string name;
ll w;
}a[201];
inline void read(ll &T) {
ll x=0;bool f=0;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=!f;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
T=f?-x:x;
}
inline void calc(int a,int b) {
ans+=a*b;
}
int main() {
read(n),read(m);
for(int i=1;i<=m;++i) {
std::cin>>a[i].name;
}
for(int i=1;i<=m;++i) {
read(a[i].w);
}
for(int i=1;i<=n;++i) {
std::cin>>sss[i];
}
for(int i=1;i<=n;++i) {
for(int j=1;j<=m;++j) {
int x=0;
while(1) {
x=sss[i].find(a[j].name,x);
if(x==-1) break;
else calc(x+1,a[j].w);
x++;
}
}
}
std::cout<<ans<<'\n';
return 0;
}