QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#462368 | #6600. Whispers of the Old Gods | yaoxi_std | AC ✓ | 1084ms | 408040kb | C++14 | 6.0kb | 2024-07-03 18:21:25 | 2024-07-03 18:21:25 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define debug(fmt, ...) \
fprintf(stderr, "[%d] " fmt "\n", __LINE__, ##__VA_ARGS__)
template <class _Tx, class _Ty>
inline void chkmin(_Tx& x, const _Ty& y) {
x = min<common_type_t<_Tx, _Ty>>(x, y);
}
template <class _Tx, class _Ty>
inline void chkmax(_Tx& x, const _Ty& y) {
x = max<common_type_t<_Tx, _Ty>>(x, y);
}
using ll = long long;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
bool Mbe;
constexpr int N = 1e4 + 10;
bool is_number(char ch) {
return '0' <= ch && ch <= '9';
}
vector<string> insert_concat(const vector<string>& tokens) {
vector<string> result;
for (int i = 0; i < (int)tokens.size(); ++i) {
result.push_back(tokens[i]);
if (i + 1 < (int)tokens.size() &&
tokens[i] != "|" &&
tokens[i] != "(" &&
tokens[i + 1] != "|" &&
tokens[i + 1] != "+" &&
tokens[i + 1] != ")")
result.push_back("-");
}
return result;
}
vector<string> get_tokens(const string& expr) {
vector<string> tokens;
tokens.push_back("("s);
for (int i = 0; i < (int)expr.size(); ++i) {
if (expr[i] == '[') {
int j = i;
while (j < (int)expr.size() && expr[j] != ']') ++j;
assert(j < (int)expr.size());
tokens.push_back(expr.substr(i, j - i + 1));
i = j;
} else {
tokens.push_back(string{expr[i]});
}
}
tokens.push_back(")"s);
// cerr << "== original tokens\n";
// for (auto it : tokens) cerr << " - $" << it << "$\n";
tokens = insert_concat(tokens);
// cerr << "== tokens with concatenations\n";
// for (auto it : tokens) cerr << " - $" << it << "$\n";
return tokens;
}
namespace nfa {
int pn;
vector<pair<int, char>> nxt[N];
int new_node() {
return ++pn;
}
void add_edge(int u, int v, char ch) {
// cerr << " - (" << u << ", " << v << ", " << ch << ")\n";
nxt[u].push_back({v, ch});
}
} // namespace nfa
template <class _Tp>
_Tp pop_back(vector<_Tp>& stk) {
_Tp ret = stk.back();
return stk.pop_back(), ret;
}
struct node {
int s, t;
};
node unary_op(const string& op, const node& u) {
if (op == "+") {
int s = nfa::new_node();
int t = nfa::new_node();
nfa::add_edge(s, u.s, '\0');
nfa::add_edge(u.t, t, '\0');
nfa::add_edge(u.t, u.s, '\0');
return {s, t};
} else if (op == "*") {
int s = nfa::new_node();
int t = nfa::new_node();
nfa::add_edge(s, u.s, '\0');
nfa::add_edge(u.t, t, '\0');
nfa::add_edge(u.s, u.t, '\0');
nfa::add_edge(u.t, u.s, '\0');
return {s, t};
} else {
assert(0);
}
}
node binary_op(const string& op, const node& u, const node& v) {
if (op == "|") {
int s = nfa::new_node();
int t = nfa::new_node();
nfa::add_edge(s, u.s, '\0');
nfa::add_edge(s, v.s, '\0');
nfa::add_edge(u.t, t, '\0');
nfa::add_edge(v.t, t, '\0');
return {s, t};
} else if (op == "-") {
nfa::add_edge(u.t, v.s, '\0');
return {u.s, v.t};
} else {
assert(0);
}
}
node get_nfa(const vector<string>& tokens) {
vector<node> stkn;
vector<string> stkop;
// cerr << "== build nfa\n";
for (auto it : tokens) {
// cerr << "=== step $" << it << "$\n";
if (it[0] == '[') {
node p;
p.s = nfa::new_node();
p.t = nfa::new_node();
for (int i = 1; i + 1 < (int)it.size(); ++i)
nfa::add_edge(p.s, p.t, it[i]);
stkn.push_back(p);
} else if (is_number(it[0])) {
node p;
p.s = nfa::new_node();
p.t = nfa::new_node();
nfa::add_edge(p.s, p.t, it[0]);
stkn.push_back(p);
} else if (it == "(") {
stkop.push_back(it);
} else if (it == ")") {
while (!stkop.empty() && stkop.back() != "(") {
string op = pop_back(stkop);
node v = pop_back(stkn), u = pop_back(stkn);
stkn.push_back(binary_op(op, u, v));
}
assert(!stkop.empty() && stkop.back() == "(");
stkop.pop_back();
} else if (it == "+" || it == "*") {
assert(!stkn.empty());
node u = pop_back(stkn);
stkn.push_back(unary_op(it, u));
} else if (it == "|") {
while (!stkop.empty() && stkop.back() == "-") {
string op = pop_back(stkop);
node v = pop_back(stkn), u = pop_back(stkn);
stkn.push_back(binary_op(op, u, v));
}
stkop.push_back(it);
} else if (it == "-") {
stkop.push_back(it);
}
// for (auto it : stkop) cerr << it << " ";
// cerr << "\n";
}
assert(stkop.empty());
assert(stkn.size() == 1);
return stkn[0];
}
int dp[N][N];
bool Med;
int main() {
// debug("Mem: %.4lfMB.", fabs(&Med - &Mbe) / 1048576);
cin.tie(0)->sync_with_stdio(0);
string str, expr;
cin >> expr >> str;
node g = get_nfa(get_tokens(expr));
int m = str.size();
memset(dp, 0x3f, sizeof(dp));
deque<tuple<int, int, int>> dq;
dq.push_back({g.s, 0, 0}), dp[g.s][0] = 0;
while (!dq.empty()) {
int x, y, d;
tie(x, y, d) = dq.front();
dq.pop_front();
if (d > dp[x][y]) continue;
if (y < m) {
if (dp[x][y + 1] > d + 1) {
dp[x][y + 1] = d + 1;
dq.push_back({x, y + 1, d + 1});
}
}
for (auto it : nfa::nxt[x]) {
int v = it.first;
char ch = it.second;
if (ch == '\0') {
if (dp[v][y] > d) {
dp[v][y] = d;
dq.push_front({v, y, d});
}
} else {
if (y < m && str[y] == ch) {
if (dp[v][y + 1] > d) {
dp[v][y + 1] = d;
dq.push_front({v, y + 1, d});
}
}
if (y < m) {
if (dp[v][y + 1] > d + 1) {
dp[v][y + 1] = d + 1;
dq.push_back({v, y + 1, d + 1});
}
}
if (dp[v][y] > d + 1) {
dp[v][y] = d + 1;
dq.push_back({v, y, d + 1});
}
}
}
}
cout << dp[g.t][m] << '\n';
return 0;
}
/*
g++ -std=c++14 -O2 -o qoj-6600 qoj-6600.cpp -Wall -Wextra
-Wshadow -fsanitize=address,undefined -g
*/
详细
Test #1:
score: 100
Accepted
time: 19ms
memory: 395328kb
input:
(5|6+)[12]3+ 4334
output:
3
result:
ok 1 number(s): "3"
Test #2:
score: 0
Accepted
time: 20ms
memory: 395300kb
input:
[12](3+|4+)+ 2345
output:
1
result:
ok 1 number(s): "1"
Test #3:
score: 0
Accepted
time: 11ms
memory: 395300kb
input:
(234|25)+ 2442342523535
output:
3
result:
ok 1 number(s): "3"
Test #4:
score: 0
Accepted
time: 3ms
memory: 395328kb
input:
(1+)|(2+) 1112212
output:
3
result:
ok 1 number(s): "3"
Test #5:
score: 0
Accepted
time: 20ms
memory: 395264kb
input:
123 12
output:
1
result:
ok 1 number(s): "1"
Test #6:
score: 0
Accepted
time: 11ms
memory: 395184kb
input:
12 123
output:
1
result:
ok 1 number(s): "1"
Test #7:
score: 0
Accepted
time: 31ms
memory: 395232kb
input:
123 23
output:
1
result:
ok 1 number(s): "1"
Test #8:
score: 0
Accepted
time: 8ms
memory: 395176kb
input:
23 123
output:
1
result:
ok 1 number(s): "1"
Test #9:
score: 0
Accepted
time: 16ms
memory: 395232kb
input:
1 2
output:
1
result:
ok 1 number(s): "1"
Test #10:
score: 0
Accepted
time: 12ms
memory: 395240kb
input:
111 11
output:
1
result:
ok 1 number(s): "1"
Test #11:
score: 0
Accepted
time: 15ms
memory: 395300kb
input:
11 111
output:
1
result:
ok 1 number(s): "1"
Test #12:
score: 0
Accepted
time: 11ms
memory: 395524kb
input:
1+ 2
output:
1
result:
ok 1 number(s): "1"
Test #13:
score: 0
Accepted
time: 4ms
memory: 395488kb
input:
1+2 2
output:
1
result:
ok 1 number(s): "1"
Test #14:
score: 0
Accepted
time: 19ms
memory: 395224kb
input:
[13][23][32] 233
output:
1
result:
ok 1 number(s): "1"
Test #15:
score: 0
Accepted
time: 15ms
memory: 395284kb
input:
00 0
output:
1
result:
ok 1 number(s): "1"
Test #16:
score: 0
Accepted
time: 8ms
memory: 395232kb
input:
0 00
output:
1
result:
ok 1 number(s): "1"
Test #17:
score: 0
Accepted
time: 20ms
memory: 395292kb
input:
0 0
output:
0
result:
ok 1 number(s): "0"
Test #18:
score: 0
Accepted
time: 44ms
memory: 396916kb
input:
(1|2)+1(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|2)(1|...
output:
1
result:
ok 1 number(s): "1"
Test #19:
score: 0
Accepted
time: 99ms
memory: 395916kb
input:
(0484|(8|(9|(198)))|(178)2126[7187645308865171]|99774(6(88(1687)+)4(8663))++((249))(3938)(7124)(314))(6|((779)))((86|04)(4375)(39|670((466))|(2701)(44|5|(4718)|9((890))+4))(8(9|(568)|[3116948995686](6382|9|7462748906210490|(490|0(349)85|(0(121))|2)+3(67|(003))++|8|640648)+((313)((072)7)0064(66(362))...
output:
149
result:
ok 1 number(s): "149"
Test #20:
score: 0
Accepted
time: 983ms
memory: 408040kb
input:
(046)965|61|((104|([2]))(((893))70|5(378))6277|41|752|012012|[6343803328803802907084854430832486850155279098472524604776748522071416414949516644524528](989(6212|216)|(9998)|80(88|((705))+5)|(89|875|2))(((553))|37|12)55(2769)(60803508|3(388|5((490)))|496|7((6(345)|2)(1030)((877|3)+[90])+67|1)(2501)[6...
output:
16
result:
ok 1 number(s): "16"
Test #21:
score: 0
Accepted
time: 503ms
memory: 397768kb
input:
(((370)7)(440)5733((175)6473|67)39((6|6227)|(9(404)0|(019(695))8[707]9)6|08|((185))|05)|(0(228)63))(([3492]+96|(5945)(007|((827))|30)((537)(4257)7|(623))6((416))(681)(686)[2501590252260068029443263942911323419]2|(582)9|843542814312326180245925650453239502011)(816257|(6(((((((303))))))))|59)+(3898)+(...
output:
27
result:
ok 1 number(s): "27"
Test #22:
score: 0
Accepted
time: 56ms
memory: 395820kb
input:
5407312253793023866322970242189685986027204962629554(1275)((1|510)+|448(823)(((696)6(437)|01+++))+(0(249)))+(469++26|255|((6967|990[3]16)0010)++(170)(719)371)|((79|97)((2(973|3)26)88)[164]|((500))5|((317)9(980607+)89((70|4760))|(329(4(350)((((476))))|3069689238030377)+1|275|54|(([4813]+4))7|5)(((([9...
output:
23
result:
ok 1 number(s): "23"
Test #23:
score: 0
Accepted
time: 232ms
memory: 395944kb
input:
(3(6|409222|117688(57|[9]7)(272|7((345)84723|(((((471))))5)|03|4)040(46((((728))))|43|43)|7[1])|69|00((310)|00)|(05897|89)36)(7|(425))((0(863)))(9|9(2078))((164)232587021598+(183))|[3](1(703)|689490303509515)53(6447)|(039)5((881)7|164[202977])(80737[08467302]|(277)|2002186+++)9|9)|(31((045)88((047)8...
output:
637
result:
ok 1 number(s): "637"
Test #24:
score: 0
Accepted
time: 1084ms
memory: 397620kb
input:
((400)3)|((716))(758|[44]+++59233(0(368))|76)(((6(993)14)|9094([1]|2))[0712173]([71]66(057|((9|((442))83)82|21214(27((358)|8)|72|0(929|6(652)0)+++((326))+))+1(26|(889)|5)[34511])(923|9042)+|78(2|724)47|(7446)(245)049412385271)((6|0(177))3)((637)41(7|034)3|08|(3(((955))))|6(55|1|(42(0206)))|3((013)))...
output:
97
result:
ok 1 number(s): "97"
Test #25:
score: 0
Accepted
time: 296ms
memory: 395936kb
input:
(269606|967(527)(8|25|9|635|((333|9|94)+)830)++|(135)+(5|(075)9|(5+++))(0|76|634)|5(310)+07|3|9[07]+87)((5(452))(435)4(799)|(4|212|((120))28|50782)+((268))92(5|01052)(68(3((270)))(8|55(0(([2])))|(5((056))6|8)2)+(08552)|7|((72|38)|458)(5|[8]34905)++|(27|9500|941712)+|(7+++)3943818629764524(2(90|765)8...
output:
32
result:
ok 1 number(s): "32"
Test #26:
score: 0
Accepted
time: 915ms
memory: 399484kb
input:
209(7650|5)+|(3|871855|(79|3(5500294(2585)32(936|0))64|(913)666(46[01])|54(77|15)++96([2])|15)((240)|(217)|71(3989|37)(((3994)))+(3|6003)6(8212728676+028|380|73(5648)2(212))|07238941198++(482)35(08|97))|44|9((((5131))6)+324038)3(61(02|90|4((2372))+|(1|(827)(7284|(040)))+4208)(4(824))4|7508|40(008)(0...
output:
31
result:
ok 1 number(s): "31"
Test #27:
score: 0
Accepted
time: 207ms
memory: 395768kb
input:
((14|((6272)67)012|013|((3246))8)(1|671)(4064|72)4816+++96)(7(8(339))+7((255)|16|6777)+[3205986669731]((([0]))|0)(83|631)(16|52045((5|8290)))|(6410|97|024(612)(395)((((189)))1|162)((439)8))+((5|(3(168))7(55|318|9)(3513)(971)|073|(07065)|20[564020294116]+[0]8)((598))(3143)|69322979++92231075092872171...
output:
310
result:
ok 1 number(s): "310"
Test #28:
score: 0
Accepted
time: 295ms
memory: 397256kb
input:
[77854229801533667435968460630510773]21((014|899)76|75|87(917)|77(9((3996))388)4)+11((7(40(840))5+++)(8|408)+7|(913|1(20|52))|([3]|3|[27](1679(((337))85441)++1(1|5132)|23)((124)5)|((7(((564)))0786|6(((993))))++25|3831)(9((397)))(0288)|7282[410385472])8((290)+|7161))+|44|5(8450)(822|9)+82|((9(776))|[...
output:
36
result:
ok 1 number(s): "36"