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;
}