给定 t 个 L 条只有循环语句的程序,判断其中是否出现了语法错误,如果没出现则判断这个程序的时间复杂度是否与给定的时间复杂度相等。
宏定义与变量(具体含义后文给出)
#define endl '\n'
typedef long long ll;
const int L = 100 + 10;
typedef pair<int, int> pii;
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define repr(i, a, b) for (int i = a; i >= b; i--)
// ----------------------------
struct node {
int depth;
string start, _end;
char val_name, type;
};
// ----------------------------
int l, w;
node code[L];
char is_use[30];
stack<pii> last_w;
// ----------------------------
int to_int(string s) {
int ans = 0;
rep(i, 0, (int)s.length() - 1) ans = ans * 10 + s[i] - '0';
return ans;
}
void input() {
cin >> l;
w = 0;
string s;
int depth = -1;
cin >> s; s.pop_back();
if (s != "O(1") w = to_int(s.substr(4));
rep(i, 1, l) {
cin >> code[i].type;
if (code[i].type == 'F') {
depth++;
cin >> code[i].val_name >> code[i].start >> code[i]._end;
}
else depth--;
code[i].depth = depth;
}
}
错误判断
F 与 E 不匹配:这个问题与括号匹配几乎相同,可以用栈或者两个计数变量都可以,此代码中使用栈因为可以同时记录另一种数据。(栈 stack<pii> last_w)
变量名重复:这就更简单了,只需要一个 bool 数组即可。(数组 is_use[30])
时间复杂度计算
void solve() {
// do!
}
使用的变量及含义:
int now_w = 0;
/*
如果第 i 条语句的类型为 F,那么 now_w 表示只看当前语句所在的一整个大代码块里,运行它前面的未结束循环和自己所用的时间复杂度为 O(n^now_w)。
如果为 E,则 now_w 的值与计算到该语句对应的 F 语句的上一层时的 now_w 的值相同,如果对应的层已是最外层,则为 0。
例如代码为
F i 1 n
F j 1 n
F k 1 n
E
F k 1 n
E
E
E
那么在结束 i=2,4,6 的循环时 now_w=2;在结束 i=3,5 时 now_w=3。
*/
int max_w = 0;
// 最大的记录过的时间复杂度中 n 的指数,也可以说这个程序的时间复杂度就是 O(n^max_w)。
int now_depth = 0;
// 表示当前处于第几层循环,如果有循环不会执行,则计算到此循环内时 now_depth 不会改变。
bool is_use[30];
// 表示现在每个小写字母(变量名)是否存在且未被销毁。(a 的下标为 0)
stack<pii> last_w;
/*
first 表示第 second 条语句的时间复杂度为多少,只计算这一个语句。(第 second 条语句类型必定是 F)
并且这个栈还正好可以判断 F 与 E 不匹配的错误,当这个语句的类型为 E 但栈已空则为错误,代码全部运行完后栈不为空也为错误。
*/