2017NOIP时间复杂度

P3952 时间复杂度题目链接[https://www.luogu.org/problemnew/show/P3952]
题目太长不在描述。
这是一道非常恶心的模拟题,考试期间一直在调试,最后半小时的时候发现输入出错了,十分的难受…
首先是输入,啥也不说,直接用string。
直接在线处理数据就可以,没有必要离线处理。
定义一个string类型的变量ans记录答案。
先判断ERR的情况,用一个int型变量f记录F的个数,遇到F就+1,遇到E就-1,记录过程中如果f<0,ans=“ERR”,记录一下。再用一个bool数组和栈记录一下变量,及时记录和销毁变量。
最后判断一下如果f!=0或者ans=“ERR"就输出"ERR”。

时间复杂度的判断直接在代码中写,比较多。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int ff[500];//用于计算时间复杂度 0表示O(1),1表示一重循环,-1表示该循环无法执行,用于终止循环
int fzd(int n)
{
	int k=0;
	for(int i=1;i<=n;i++)
	{
		if(ff[i]==1)k++;
		if(ff[i]==-1)return k;//当ff=-1是后面的循环无法执行,直接跳出
	}
	return k;
}
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n;
		string s,ans;
		cin>>n>>s;
		int f=0;memset(ff,0,sizeof(ff));
		bool BL[500];memset(BL,0,sizeof(BL));//用于判断变量有没有用过
		int stack[500],top=0;memset(stack,0,sizeof(stack));//模拟堆栈
		//记住一定要初始化
		int FZD=0;//用于记录最大复杂度
		while(n--)
		{
			char C;
			cin>>C;
			if(C=='F'){
				f++;
			}
			else 
			{	
				ff[f]=0;
				BL[stack[top--]]=false;//销毁过期变量
				f--;
				if(f<0)ans="ERR";//不合法
				continue;
			}
			char B;
			cin>>B;
			if(BL[(int)B])ans="ERR";
			else{
				BL[(int)B]=true;
				stack[++top]=(int)B;
			}
			string l,r;
			cin>>l>>r;
			//判断复杂度
			if(l[0]>='0'&&l[0]<='9'&&r[0]=='n')//该循环表示为  常数~n,复杂度为n
			{
				ff[f]=1;
				FZD=max(FZD,fzd(f));
			}
			else if(l[0]=='n'&&r[0]>='0'&&r[0]<='9')//该情况为无法执行的循环
			{
				ff[f]=-1;
				FZD=max(FZD,fzd(f));
			}
			else if(l[0]>='0'&&l[0]<='9'&&r[0]>='0'&&r[0]<='9')//循环的上界和下界均为常数
			{
				if(l.size()>r.size())ff[f]=-1;//前面的数小  循环无法执行,记录为-1
				else if(l.size()==r.size()&&l>r)ff[f]=-1;//前面的数小  循环无法执行,记录为-1
				FZD=max(FZD,fzd(f));
			}
			else FZD=max(FZD,fzd(f));//其他情况复杂度均为常数,记录为0,数组初始化为0,所以不用再次赋值
		}
		if(ans=="ERR"||f!=0){
			cout<<"ERR"<<endl;//记住千万不要输出ans,因为当f>0是ans为空。
		}
		else
		{
			if(s[2]=='1')
			{
				if(FZD==0)cout<<"Yes"<<endl;
				else cout<<"No"<<endl;
			}
			else
			{
				int k=4;
				int x=0;
				while(s[k]!=')')//提取O(n^w)中的w
				{
					x=x*10+s[k]-'0';
					k++;
				}
				if(x==FZD)cout<<"Yes"<<endl;
				else cout<<"No"<<endl;
			}
		}
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值