P3333 [ZJOI2013]丽洁体
作者:互联网
想要一直爱着某物的话,以妖怪之生来说太长了;
想要实现一切梦想的话,以人类之生来说太短了。
写这题的动机只是这两句话= =
简述
原题面:Luogu
给定字符串 \(T,A,B,C\),每个字符串都由一些由空格分隔的单词构成。
求至少需要在 \(T\) 中删除多少单词,使得 \(T\) 呈现 \(A\cdots B\cdots C\) 的形式。
保证有解。
\(1\le |T|,|A|,|B|,|C|\le 5\times 10^4\),所有单词长度 \(\le 5\),每种单词出现次数 \(\le 500\)。
1S,512MB。
分析
知识点:哈希,贪心,暴力。
先把所有字符串中的所有单词 Hash 一下。
显然,对于最后保留串中的 \(A\) 和 \(C\),在 \(T\) 中距离越远越好,贪心从 \(T\) 两侧找即可,时间复杂度 \(O(|T|)\)。
再从找到的 \(AC\) 中间找 \(B\),每种单词出现次数 \(\le 500\),暴力枚举 \(B\) 的第一个位置,再贪心的找即可,时间复杂度上界 \(O(500|T|)\)。
总时间复杂度上界是 \(O(500|T|)\),可过。
实现
//知识点:哈希,暴力,贪心
/*
By:Luckyblock
*/
#include <algorithm>
#include <cctype>
#include <cstdio>
#include <cstring>
#define LL long long
const int kN = 3e5 + 10;
//=============================================================
char t[kN], a[kN], b[kN], c[kN];
int ans, lt, la, lb, lc;
int hast[kN], hasa[kN], hasb[kN], hasc[kN];
//=============================================================
inline int read() {
int f = 1, w = 0;
char ch = getchar();
for (; !isdigit(ch); ch = getchar())
if (ch == '-') f = -1;
for (; isdigit(ch); ch = getchar()) {
w = (w << 3) + (w << 1) + (ch ^ '0');
}
return f * w;
}
void Chkmax(int &fir_, int sec_) {
if (sec_ > fir_) fir_ = sec_;
}
void Chkmin(int &fir_, int sec_) {
if (sec_ < fir_) fir_ = sec_;
}
void Has(char *s_, int *has_, int &l_) {
int lth = strlen(s_);
for (int i = 0; i < lth; ++ i) {
if (s_[i] < 'a' || s_[i] > 'z') continue ;
if (i == 0 || s_[i - 1] < 'a' || s_[i - 1] > 'z') has_[++ l_] = 0;
has_[l_] = 27 * has_[l_] + s_[i] - 'a' + 1;
}
}
void Prepare() {
gets(t), gets(a), gets(b), gets(c);
Has(t, hast, lt);
Has(a, hasa, la);
Has(b, hasb, lb);
Has(c, hasc, lc);
}
//=============================================================
int main() {
Prepare();
int l = 0, r = 0, lth;
for (l = 1, lth = 1; l <= lt; ++ l) {
if (hast[l] == hasa[lth]) {
if (lth == la) {
++ l;
break;
}
++ lth;
continue;
}
++ ans;
}
for (r = lt, lth = lc; r >= 1; -- r) {
if (hast[r] == hasc[lth]) {
if (lth == 1) {
-- r;
break;
}
-- lth;
continue;
}
++ ans;
}
int mincost = lt;
for (int i = l; i <= r; ++ i) {
if (hast[i] != hasb[1]) continue;
int l = 0, cost = 0;
for (int j = i; j <= r; ++ j) {
if (hast[j] == hasb[l + 1]) {
++ l;
if (l == lb) break;
continue ;
}
++ cost;
}
if (l == lb) Chkmin(mincost, cost);
}
printf("%d\n", ans + mincost);
return 0;
}
标签:fir,P3333,ch,int,丽洁体,kN,ZJOI2013,le,lth 来源: https://www.cnblogs.com/luckyblock/p/13968425.html