8 2 O(1) F i 11 E 2 O(n^1) F x 1 n E 1 O(1) F x 1 n 4 O(n^2) F x 5 n F y 10 n E E 4 O(n^2) F x 9 n E F y 2 n E 4 O(n^1) F x 9 n F y n 4 E E 4 O(1) F y n 4 F x 9 n E E 4 O(n^2) F x 1 n F x 110 E E
输出样例
1 2 3 4 5 6 7 8
Yes Yes ERR Yes No Yes Yes ERR
解题思路
首先我们肯定一眼就能看出这题是个没有任何优化的大模拟
那么如何模拟?
首先我们为了方便,把循环体离线下来,用字符串存着
根据题意,我们写一个函数GetNumber()把字符串里的数字存下来 具体和快读差不多
我们先把小明给出的时间复杂度的的指数记为,这里注意的情况要用代替
接着便是求真正的时间复杂度了
首先是判断ERR 这个比较简单 我们用一个栈来储存所有的循环体的变量名
当已经读完但是栈不空
当未读完但是栈空
当储存的变量名与现在的变量名冲突
这个过程穿插在代码各处
当读到的时候往栈里 Push 循环体变量名,注意要一块把记录变量名的数组used进行判断并更新
之后,我们用GetNumber获取一下和两个数,分情况讨论一下
当是的时候,如果这次循环可以执行,++答案
当的时候,循环不执行,更新一下「最早不能循环的循环体」
剩下一种情况就是常数,可以不写
当读到的时候,先检查栈里还有没有东西,再 Pop 出来,注意要检查一下这个变量是不是「最早不能循环的循环体」的变量
intGetNumber(int &X, string s){ int len = s.length(); while (!isdigit(s[X]) && X < len) { if (s[X] == 'n') { ++X; return19260817; } ++X; } int ret = 0; while (isdigit(s[X])) { ret = ret * 10 + s[X] - '0'; ++X; } return ret; }
intgetO(string s){ if (s[2] == 'n') { int _ = 3; // 必须要传实参进去 return GetNumber(_, s); } return0; }
intGetO(int l){ int ret = 0; int now = 0; char earliestVariant = -1; // 「最早不能循环的循环体」 int x = 0, y = 0; stack<int> stk; bool used[27] = { false }; bool ran[27] = { false }; for (int i = 1; i <= l; ++i) { if (Code[i][0] == 'F') { char varName = Code[i][2]; if (used[varName - 'a']) return-1; stk.push(varName); used[varName - 'a'] = true; // Get X int X = 4; x = GetNumber(X, Code[i]); // Get Y y = GetNumber(X, Code[i]); if (y - x > 1000) { // y = n if (earliestVariant == -1) { ++now; ret = std::max(ret, now); ran[varName - 'a'] = true; } } elseif (x > y) { if (earliestVariant == -1) earliestVariant = varName; } } else { if (stk.empty()) return-1; char nowVarName = stk.top(); stk.pop(); used[nowVarName - 'a'] = false; if (earliestVariant == nowVarName) earliestVariant = -1; if (ran[nowVarName - 'a']) { ran[nowVarName - 'a'] = false; --now; } } } if (!stk.empty()) return-1; return ret; }
intmain(){ scanf("%d", &t); while (t --> 0) { int w, nw, l; scanf("%d ", &l); string o; getline(cin, o); nw = getO(o); for (int i = 1; i <= l; ++i) { getline(cin, Code[i]); } w = GetO(l); if (w == -1) puts("ERR"); else { if (w == nw) puts("Yes"); elseputs("No"); } } return0; }