NOIP2017D1T2 时间复杂度 题解

(题目描述略)

注意以下情况:

  1. FE 不匹配导致 ERR,包括 F 多于 E 导致代码结束后循环未全部跳出,和 F 少于 E 导致代码执行过程中跳出代码块(该情况下可能局部 F 少于 E,但全局 F 等于 E)两种情况;
  2. 循环中可能包含多个同级循环,故需栈保存当前循环变量名和当前循环复杂度,F 进栈,E 出栈;
  3. 循环变量名生存期为相应循环 F 到 E,出栈后即刻销毁,不参与之后变量名同名查询;
  4. 循环范围 x 到 y 有以下三种情况:(字母 n 的 ASCII 码大于 100,可简化代码)
    第一种情况:x 为常数,y 为 n,当前循环复杂度为前层循环复杂度加一;
    第二种情况:x 为常数,y 为常数且 x ≤ y,或 x 和 y 都为 n,当前循环复杂度等于前层循环复杂度;
    第三种情况:x 为常数,y 为常数且 x > y,或 x 为 n,y 为常数,当前循环及其子循环复杂度都等于前层循环复杂度,即该循环恒不被执行。

代码如下:

#include<stdio.h>
char o[10];
int stki[30],stkin[30],stkw[30];
int main()
{
	freopen("complexity.in","r",stdin);
	freopen("complexity.out","w",stdout);
	bool err;
	char fe,i;
	int l,t,wm,wn,x,y;
	scanf("%d",&t);
	stki[0]=stkw[0]=0;
	for(int j=0;j<26;j++)
		stkin[j]=0;
	while(t--)
	{
		scanf("%d %s",&l,o);
		if(o[2]=='n')
			if(o[6])
				wn=(o[4]-'0')*10+(o[5]-'0');
			else
				wn=o[4]-'0';
		else
			wn=0;
		err=false,wm=0;
		while(l--)
		{
			scanf(" %c",&fe);
			if(fe=='F')
			{
				scanf(" %c",&i);
				if(scanf("%d",&x)==0)
					scanf(" %c",&x);
				if(scanf("%d",&y)==0)
					scanf(" %c",&y);
				if(stkin[i-'a']>0)
					err=true;
				stkin[stki[++stki[0]]=i-'a']++;
				if(x!='n'&&y=='n')
					stkw[stki[0]]=stkw[stki[0]-1]+1;
				else if(x<=y)
					stkw[stki[0]]=stkw[stki[0]-1];
				else
					stkw[stki[0]]=-100;
				if(wm<stkw[stki[0]])
					wm=stkw[stki[0]];
			}
			else
				if(stki[0]>0)
					stkin[stki[stki[0]--]]--;
				else
					err=true;
		}
		if(stki[0]>0)
			for(err=true;stki[0]>0;stkin[stki[stki[0]--]]--);
		puts(!err?wm==wn?"Yes":"No":"ERR");
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值