P8085 [COCI2011-2012#4] KRIPTOGRAM 题解
1.AT_abc333_e [ABC333E] Takahashi Quest 题解2.[ABC265F] Manhattan Cafe 题解3.[ABC271E] Subsequence Path 题解4.[ABC273D] LRUD Instructions 题解
5.P8085 [COCI2011-2012#4] KRIPTOGRAM 题解
6.[ABC238F] Two Exams 题解7.[ABC217F] Make Pair 题解8.[ABC219F] Cleaning Robot 题解9.[ABC219E] Moat 题解10.[ABC221D] Online games 题解11.[ABC221E] LEQ 题解12.[ABC223E] Placing Rectangles 题解13.[ABC211D] Number of Shortest paths 题解14.[ABC211F] Rectilinear Polygons 题解15.[ABC223F] Parenthesis Checking 题解16.CF154C Double Profiles 题解17.[ABC208D] Shortest Path Queries 2 题解18.[ABC212E] Safety Journey 题解19.[ABC229E] Graph Destruction 题解20.[ABC240E] Ranges on Tree 题解21.[ABC261E] Many Operations 题解22.P10842 【MX-J2-T3】Piggy and Trees 题解P8085 [COCI2011-2012#4] KRIPTOGRAM 题解
本文原发布于2024-02-07洛谷题库 P8085 [COCI2011-2012#4] KRIPTOGRAM 题解区,现于2024-2-29转载至博客园
思路解析
这道题目的主要难点在于如何判断明文中形如
接下来就要判断密文所对应的匹配数组是否在明文当中出现过,考虑使用滑动窗口做法。但由于删除子字符串会导致新的明文的匹配数组发生改变,所以我们需要同时存下来下一个与当前字符串相同的字符串的位置。原因是如果删掉一个明文的子字符串就会导致下一个与当前字符串相同的字符串的匹配数组的值变为
最后我们就需要把已经求出来的两个匹配数组进行判断比较,但是如果对于每一个明文的子字符串都从头到尾比较一次的话时间复杂度就会达到
code
#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
const int N = 1e6 + 10;
const ull P = 13331;
string a[N], b[N];
ull p[N], l1[N], l2[N], t1[N];
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
string s1, s2;
int n1 = 1, n2 = 1;
cin >> s1;
for(; s1 != "$"; n1++) {
a[n1] = (s1);
cin >> s1;
}
cin >> s2;
for(; s2 != "$"; n2++) {
b[n2] = (s2);
cin >> s2;
}
n1--; n2--;
p[0] = 1;
for(int i = 1; i <= n1; i++) {
p[i] = p[i - 1] * P;
}
map<string, int> mp1, mp2;
ull h1 = 0, h2 = 0;
for(int i = 1; i <= n2; i++) {
if(mp1[a[i]] != 0) {
l1[i] = i - mp1[a[i]];
t1[mp1[a[i]]] = i;
}
else l1[i] = 0;
mp1[a[i]] = i;
h1 = h1 * P + l1[i];
if(mp2[b[i]] != 0) {
l2[i] = i - mp2[b[i]];
}
else l2[i] = 0;
mp2[b[i]] = i;
h2 = h2 * P + l2[i];
}
if(h1 == h2) {
cout << 1;
return 0;
}
for(int i = 2; i + n2 - 1 <= n1; i++) {
int r = i + n2 - 1;
h1 = (h1 - l1[i - 1] * p[n2 - 1]) * P;
if(mp1[a[i - 1]] == i - 1) {
mp1[a[i - 1]] = 0;
}
if(t1[i - 1] != 0) {
h1 -= l1[t1[i - 1]] * p[r - t1[i - 1]];
l1[t1[i - 1]] = 0;
}
if(mp1[a[r]] != 0) {
l1[r] = r - mp1[a[r]];
t1[mp1[a[r]]] = r;
}
else l1[r] = 0;
mp1[a[r]] = r;
h1 += l1[r];
if(h1 == h2) {
cout << i;
return 0;
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】