1900:【17NOIP提高组】时间复杂度

【题目描述】

给出了他自己算出的时间复杂度,可他的编程老师实在不想一个一个检查小明的程序,于是你的机会来啦!下面请你编写程序来判断小明对他的每个程序给出的时间复杂度是否正确。 A++A++ 语言的循环结构如下:

F i x y

循环体

E

然后判断 ii 和 yy 的大小关系,若 ii 小于等于 yy 则进入循环,否则不进入。每次循环结束后 ii 都会被修改成 i+1i+1,一旦 ii 大于 yy 终止循环。 xx 和 yy 可以是正整数(xx 和 yy 的大小关系不定)或变量 nn。nn 是一个表示数据规模的变量,在时间复杂度计算中需保留该变量而不能将其视为常数,该数远大于 100100。 EE表示循环体结束。循环体结束时,这个循环体新建的变量也被销毁。

注:本题中为了书写方便,在描述复杂度时,使用大写英文字母 OO 表示通常意义下 ΘΘ 的概念。

【输入】

第一行一个正整数 tt,表示有 t(t≤10)t(t≤10) 个程序需要计算时间复杂度。

每个程序我们只需抽取其中 FixyFixy和EE即可计算时间复杂度。注意:循环结构允许嵌套。

接下来每个程序的第一行包含一个正整数 LL 和一个字符串,LL 代表程序行数,字符串表示这个程序的复杂度,O(1)O(1)表示常数复杂度,O(nO(n^w)w) 表示复杂度为 nwnw ,其中 ww 是一个小于 100100 的正整数(输入中不包含引号),输入保证复杂度只有 O(1)O(1) 和 O(nO(n^w)w) 两种类型。

接下来 LL 行代表程序中循环结构中的 FixyFixy 或者 EE。 程序行若以 FF 开头,表示进入一个循环,之后有空格分离的三个字符(串)ixyixy,其中 ii 是一个小写字母(保证不为 nn ),表示新建的变量名,xx 和 yy 可能是正整数或 nn ,已知若为正整数则一定小于 100100。 程序行若以 EE开头,则表示循环体结束。

【输出】

输出共 tt 行,对应输入的 tt 个程序,每行输出YesYes或NoNo或者ERRERR,若程序实际复杂度与输入给出的复杂度一致则输出 YesYes,不一致则输出NoNo,若程序有语法错误(其中语法错误只有: ①FF 和 EE 不匹配 ②新建的变量与已经存在但未被销毁的变量重复两种情况),则输出ERRERR。

注意:即使在程序不会执行的循环体中出现了语法错误也会编译错误,要输出ERRERR。

【输入样例】

8

2 O(1)

F i 1 1

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 1 10

E

E

【输出样例】

Yes

Yes

ERR

Yes

No

Yes

Yes

ERR

【提示】

【样例说明】

第一个程序 ii 从11 到 11 是常数复杂度。

第二个程序 xx 从 11 到 nn 是 nn 的一次方的复杂度。

第三个程序有一个 FF 开启循环却没有E结束,语法错误。

第四个程序二重循环,nn 的平方的复杂度。

第五个程序两个一重循环,nn 的一次方的复杂度。

第六个程序第一重循环正常,但第二重循环开始即终止(因为 nn 远大于 100100,100100 大于 44)。

第七个程序第一重循环无法进入,故为常数复杂度。

第八个程序第二重循环中的变量 xx 与第一重循环中的变量重复,出现语法错误②,输出 ERRERR。

【数据范围】

对于 30% 的数据:不存在语法错误,数据保证小明给出的每个程序的前 L/2L/2 行一定为以 FF 开头的语句,第 L/2+1L/2+1 行至第 LL 行一定为以 EE 开头的语句,L≤10L≤10,若 xx,yy 均为整数,xx 一定小于 yy,且只有 yy 有可能为 nn。

对于 50% 的数据:不存在语法错误,L≤100L≤100,且若 xx,yy 均为整数,xx 一定小于 yy,且只有 yy 有可能为 nn。

对于 70% 的数据:不存在语法错误,L≤100L≤100。

对于 100% 的数据:t≤10,L≤100t≤10,L≤100。

样例数据下载

代码整体如下:

#include<cctype>

#include<cstdio>

#include<cstring>

#include<iostream>

#include<algorithm>

#define N 105

#define oo 10000

using namespace std;

int sta[N], a[N];

bool can[N], used[30];

char s[10], var[N], num1[10], num2[10];

void init() {

memset(a, 0, sizeof(a));

memset(can, true, sizeof(can));

memset(used, false, sizeof(used));

}

int get1(char *a) {

int i = 4, ans = 0;

while (isdigit(a[i])) {

ans = ans * 10 + a[i] - '0';

i++;

}

return ans;

}

int get2(char *a) {

int i, l, num = 0;

if (a[0] == 'n')

return oo;

l = strlen(a);

for (i = 0; i < l; ++i)

num = num * 10 + a[i] - '0';

return num;

}

int main() {

char c;

bool flag;

int n, i, t, x, y;

int top, num, sum, maxn;

cin >> t;

while (t--) {

cin >> n >> s;

init();

num = get1(s);

flag = true;

top = 0, sum = 0, maxn = 0;

for (i = 1; i <= n; ++i) {

cin >> c;

if (c == 'F') {

cin >> var[i] >> num1 >> num2;

if (!flag) continue;

x = get2(num1);

y = get2(num2);

if (used[var[i] - 'a'])

flag = false;

sta[++top] = i;

used[var[i] - 'a'] = true;

if (x < y && y == oo) a[i] = 1, sum++;

if (x > y || !can[top - 1]) can[top] = false;

} else {

if (!flag) continue;

if (top == 0) flag = false;

used[var[sta[top]] - 'a'] = false;

if (can[top]) maxn = max(maxn, sum);

if (a[sta[top]]) sum--;

can[top] = true;

top--;

}

}

if (top != 0) flag = false;

if (!flag) cout << "ERR" << '\n';

else {

if (maxn == num) cout << "Yes" << '\n';

else cout << "No" << '\n';

}

}

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值