【做题】sgu189 Perl-like Substr——dark模拟

时间:2023-03-10 02:44:00
【做题】sgu189 Perl-like Substr——dark模拟

注:这篇博客纯属为凑篇数而生。

题面较长,幸运的是,网上给出了相当不错的翻译

需要支持的操作很简单,即对子串提取、赋值和输出,且对时间复杂度没有要求。换言之此题有成为块链毒瘤题的潜质。难点在于输入的格式是类似于源代码的,但形式单一,变量前均有$字符标注,可以通过直接判断来解决。于是就只需要大力讨论就可以了。

这或许就是所谓的题意即题解吧。

时间复杂度O(m*l)。

 #include <bits/stdc++.h>
using namespace std;
const int N = , LN = ;
string var[N], tmp, tp;
int node[N * LN][], tag[N * LN], cnt, tot = , pos;
inline int read() {
int res = ; bool key = ;
for (; !(tmp[pos] >= '' && tmp[pos] <= '') ; ++ pos)
key = (tmp[pos] == '-');
for (; tmp[pos] >= '' && tmp[pos] <= '' ; ++ pos)
res = (res << ) + (res << ) + tmp[pos] - '';
if (key) res = - res;
return res;
}
inline int get_val(char x) {
if (x >= '' && x <= '') return x - '';
if (x >= 'a' && x <= 'z') return x - 'a' + ;
if (x >= 'A' && x <= 'Z') return x - 'A' + ;
return -;
}
inline bool invar(char x) {
return (x >= '' && x <= '') || (x >= 'a' && x <= 'z') || \
(x >= 'A' && x <= 'Z') || x == ' ' || x == ',' || x == '.' || \
x == '-' || x == '_' || x == ':' || x == '!' || x == '?';
}
int find(string s) {
int l = s.length(), p = , t;
for (int i = ; i < l ; ++ i) {
t = get_val(s[i]);
if (!node[p][t]) node[p][t] = ++ tot;
p = node[p][t];
}
if (!tag[p]) {
tag[p] = ++ cnt;
var[cnt] = "";
}
return tag[p];
}
int get_tag() {
tp = "";
while (~get_val(tmp[++ pos]))
tp += tmp[pos];
return find(tp);
}
void solve_init() {
int l = tmp.length(), p;
tp = "";
for (pos = ; pos < l ; ++ pos) {
if (tmp[pos] == '$') {
var[p = get_tag()] = "";
break;
}
}
while (tmp[pos] != '"') ++ pos;
for (++ pos ; invar(tmp[pos]) ; ++ pos) {
var[p] += tmp[pos];
}
}
void subst(int& p,int& l,int& n) {
while (tmp[pos] != '$') ++ pos;
p = get_tag();
int len = var[p].length(), be, co;
be = read();
while (tmp[pos] != ',' && tmp[pos] != ')') ++ pos;
if (tmp[pos] == ')') co = ;
else co = read();
l = be >= ? be : len + be;
n = co >= ? co > ? co : len - l : len + co - l;
while (tmp[pos] != ')') ++ pos;
++ pos;
}
void print() {
while (tmp[pos] != '$' && tmp[pos] != 's') ++ pos;
int p,l,n;
if (tmp[pos] == '$') {
p = get_tag();
cout << var[p] << endl;
} else {
subst(p,l,n);
cout << var[p].substr(l,n) << endl;
}
while (tmp[pos] != ')') ++ pos;
++ pos;
}
void solve() {
int l = tmp.length(), p1, p2, l1, n1, l2, n2, t1, t2;
for (pos = ; tmp[pos] == ' ' ; ++ pos);
switch(tmp[pos]) {
case 's':subst(p1,l1,n1), t1 = ; break;
case 'p':print(); return;
case '$':p1 = get_tag(), t1 = ; break;
}
for (; tmp[pos] != '$' && tmp[pos] != 's' ; ++ pos);
switch(tmp[pos]) {
case 's':subst(p2,l2,n2), t2 = ; break;
case '$':p2 = get_tag(), t2 = ; break;
}
if ((!t1) && (!t2)) var[p1] = var[p2];
else if ((!t1) && t2) var[p1] = var[p2].substr(l2,n2);
else if (t1 && (!t2)) var[p1].replace(l1,n1,var[p2]);
else if (t1 && t2) var[p1].replace(l1,n1,var[p2],l2,n2);
}
int main() {
int n,m;
scanf("%d%d\n",&n,&m);
for (int i = ; i <= n ; ++ i) {
getline(cin,tmp);
solve_init();
}
for (int i = ; i <= m ; ++ i) {
getline(cin,tmp);
solve();
}
return ;
}

小结:续了一个下午……代码能力不够的问题。