【题解】NOIP2017 D1T2时间复杂度
题解 NOIP2017 D1T2时间复杂度
题意:给一个简化的只有循环的代码,计算时间复杂度。
模拟,本人码力很差,陆陆续续调了好几天才出来。。
用一个栈模拟循环,遇到 F 入栈,遇到 E 出栈。
语法错误的情况就维护一个 used 数组记录用没用过这个变量,而且当遇到 E 但是栈已经空了又或者程序结束栈还不是空的就报错。
怎样维护循环无法进行的情况?(要注意,\(x=y=n\) 的情况也无法进行循环)
可以把 used 数组的值设为这个循环的层数,当无法执行循环的时候就设置一个变量 brk ,记录为再哪一层循环中断了,等到出栈的时候如果又回到了那一层就可以把 brk 再设为 0 了。
#include<bits/stdc++.h>
using namespace std;
int used[50];
int t, l;
string O;
struct cmd
{
string type, i, x, y;
};
stack<cmd> s;
int main()
{
ios::sync_with_stdio(false);
cin >> t;
while (t--)
{
int ON = 0, brk = 0, ceng = 0;
bool if_ERR = 0;
while (!s.empty())
s.pop();
memset(used, 0, sizeof(used));
cin >> l >> O;
int cnt = 0;
string x, y, p, i;
for (int k = 0; k < l; k++)
{
cin >> p;
if (p[0] == 'F')
{
cin >> i >> x >> y;
if (if_ERR) continue;
if (used[i[0] - 'a']) // 变量用过了
{
cout << "ERR\n";
if_ERR = 1;
continue;
}
used[i[0] - 'a'] = ++ceng;
if (isdigit(x[0]) && y == "n" && !brk)
ON++;
else if (x == "n" && isdigit(y[0]) && !brk)
brk = ceng;
else if (!brk && isdigit(x[0]) && isdigit(y[0]) && stoi(x) > stoi(y))
brk = ceng;
s.push((cmd) { "F", i, x, y });
}
else
{
if (if_ERR)
continue;
cmd now;
if (s.empty())
{
cout << "ERR\n";
if_ERR = 1;
continue;
}
else
{
now = s.top();
s.pop();
}
ceng--;
if (used[now.i[0] - 'a'] == brk)
brk = 0;
cnt = max(ON, cnt);
if (!brk && isdigit(now.x[0]) && now.y == "n")
ON--;
used[now.i[0] - 'a'] = 0;
}
}
if (if_ERR == 1)
continue;
else if (!s.empty())
{
cout << "ERR" << endl;
}
else if (cnt == 0)
{
if (O == "O(1)")
cout << "Yes" << endl;
else
cout << "No" << endl;
}
else if (cnt != 0)
{
string ans = "O(n^" + to_string(cnt) + ")";
if (ans == O)
cout << "Yes\n";
else
cout << "No\n";
}
}
return 0;
}