洛谷 P3952 [NOIP2017 提高组] 时间复杂度

Description

P3952 [NOIP2017 提高组] 时间复杂度

Solution

膜你模拟

这题很久之前刚开始学 (OI) 的时候做过一次,当时着实被虐了好几个小时才做出来,还是看了题解的。

于是怀恨在心,总之现在来复盘一下,感觉还可以,多想想,细节也不算太多。

emm没什么好说的了,直接看代码吧(有注释)。

Code

#include <bits/stdc++.h>

using namespace std;

int T, l;
char o[1000];
int stk[110], top, maxt, tim, flag, t;
//stk:记录每一层循环能否进入,且是否贡献复杂度。 1:能进入但不贡献复杂度		2:不能进入		3:能进入且贡献复杂度	top:栈顶
//maxt:记录最终出的时间复杂度。(max{tim})
//tim:可能存在并列的循环,所以记录每一时刻的时间复杂度
//flag:是否有编译错误。
//t:题目中输入的时间复杂度。
char op, x, a[10], b[10];
//输入的4个变量。
int tc[110];
//和栈同时更新,记录每一层循环的变量是多少。
bool vis[30];
//桶,用来快速判断一个变量是否被用过。

int zs(char c[]){//把 F i x y 中的 x 和 y 提取出来,判断能否进入这个循环
	if(strlen(c) == 1) return c[0] - '0';
	else return 10 * (c[0] - '0') + (c[1] - '0');//小于100
}

void calc(){//把输入的复杂度提取出来,就是那个O(n^w)中的 w
	if(o[2] == 'n'){
		if(o[5] == ')') t = o[4] - '0';
		else t = 10 * (o[4] - '0') + (o[5] - '0');//w < 100
	}
	else t = 0;//常数的话,复杂度为0
}

int main(){
	scanf("%d", &T);
	while(T--){
		top = flag = maxt = tim = 0;//多测清空
		memset(vis, 0, sizeof(vis));
		memset(tc, 0, sizeof(tc));
		cin >> l >> o;
		calc();//计算输入的时间复杂度
		for(int i = 1; i <= l; i++){
			cin >> op;
			if(op == 'F'){
				cin >> x >> a >> b;
				if(vis[x - 'a']){//如果当前变量被用过。
					flag = 1;//编译错误
					top++;//还得压栈,不然后面输入就乱了。
					continue;
				}
				if(stk[top] == 2){//上一层循环无法进入
					stk[++top] = 2;//传递标记
					continue;
				}
				tc[++top] = x - 'a';//当前变量入栈
				vis[x - 'a'] = 1;//给桶打上标记
				if(a[0] != 'n' && b[0] != 'n'){//两个都是数字
					if(zs(a) <= zs(b)) stk[top] = 1;//1:可以进入
					else stk[top] = 2;//2:无法进入
				}else{//有至少一个是n
					if(a[0] != 'n' && b[0] == 'n') stk[top] = 3, tim++;//3: 复杂度+1 
					if(a[0] == 'n' && b[0] != 'n') stk[top] = 2;
					if(a[0] == 'n' && b[0] == 'n') stk[top] = 1;
				}
				maxt = max(maxt, tim);//更新复杂度最大值
			}else{
				if(!top){//栈已经空了,还在退出,直接编译错误
					flag = 1;
					continue;
				}
				if(stk[top] == 3) tim--;//判断对应循环是否贡献复杂度,如果贡献,tim--
				vis[tc[top--]] = 0;//删去对应循环变量在桶中的标记
				maxt = max(maxt, tim);//这个可以不写(好像)
			}
		}
		if(flag || top || (l & 1)) puts("ERR");//编译错误(不完全)|| 桶中还有元素 || 输入长度为奇数
		else if(maxt == t) puts("Yes");
		else puts("No");
	}
	return 0;
}

End

本文来自博客园,作者:xixike,转载请注明原文链接:https://www.cnblogs.com/xixike/p/15173806.html

原文地址:https://www.cnblogs.com/xixike/p/15173806.html