测评会员优惠活动进行中 · 开通 VIP,有效期内测评不限次 VIP 优惠中 · 测评不限次 立即查看

A39216. 谜【

填空题 困难

题目描述

谜

【题目描述】

二战期间,德军使用一种名为“Enigma”的密码机。这个密码机最终被盟军破解的关键之一,是来自于使用它的人的习惯。德军每天发送的电报中,会有很多重复的词语,比如问候语、结尾的落款、每天的天气等等。盟军的破解人员把这些重复出现的词语称作“crib”。知道了“crib”,还要知道“crib”在密文中的什么位置。由于“Enigma”是通过电路加密,所以一

个字母加密后绝对不会仍然是自身,这个特性可以帮助我们定位“crib”的位置。

例如盟军截获了一条密文"XEQFTWRWEVTRES",并且我们猜测原文中可能含有"WETTER"这个词。因为字母绝对不会被加密成自身,所以当我们将"WETTER"这个词和密文去比对,就可以找到这个词可能的位置。

在下面这个位置时,"WETTER"和密文对应的每个位置的字母都不相同,所以这条密文的原文中可能含有"WETTER"。

一条密文中可能含有不止一种“crib”,同一种“crib”也可能出现多次,“crib”所占据的位置不能有重叠。给出所有可能的“crib”和一条密文,你要求出这条密文中可能包含的“crib”的最多个数。

【输入格式】

第 1 行,1 个正整数 n,表示有 n 种“crib”。

接下来 n 行,每行一个字符串,表示 1 种“crib”。

最后 1 行,1 个字符串,表示密文。

【输出格式】

输出 1 个整数,表示密文中可能包含的“crib”的最大个数。

【输入样例 1】

2

WETTER

XORT

XEQFTWROEXGRES

【输出样例 1】

2

【输入样例 2】

2

CRYTIC

OVULIST

CCNDDZIYXDSMTOS

【输出样例 2】

2

【输入样例 3】

3

RUBRA

DOING

GRATED

XMQWVBJAMMRGCOXQPFIZOBMDUYOXJNGTTNRJOHLD

【输出样例 3】

8

【说明提示】

样例 1 说明:

如下安排两个 crib 的位置,最多包含 2 个 crib。

crib 也可能在如下两个位置,仍然是包含 2 个 crib。

样例 2 说明:

如下安排两个 crib 的位置,最多包含 2 个 crib。

【数据范围】

对 10%数据:n=1

另有 10%数据满足:所有“crib”的长度都等于 1。

对 100%数据:1≤n≤50;“crib”互不相同。“crib”的长度不超过 50,密文的长度不超过 105,输入中所有字符串只含大写英文字母。

参考答案

#include<cstdio> #include<cstring> #include<iostream> #include<cmath> #include<string> #include<algorithm> #include<vector> #include<queue> #include<stack> #include<map> using namespace std; typedef long long LL; const int MR=1e5+10; bool check(const string &x,const string &y) { if(x.size()!=y.size()) return false; int l=x.size(); for (int i=0;i<l;i++) { if(x[i]==y[i]) return false; } return true; } int n,dp[MR],cL[51]; string s,crib[51]; int main() { cin>>n; for (int i=1;i<=n;i++) { cin>>crib[i]; cL[i]=crib[i].size(); } cin>>s; int len=s.size(); for (int i=1;i<=len;i++) { dp[i]=dp[i-1]; for (int j=1;j<=n;j++) { if(i>=cL[j] && check(s.substr(i-cL[j],cL[j]),crib[j])) { dp[i]=max(dp[i-cL[j]]+1,dp[i]); } } } cout<<dp[len]<<endl; return 0; }
上一题 下一题