以后直接放链接了,哈哈蛤……
#2748 时间复杂度
SOL
循环的结构很简单:
F i x y
循环体
E
但是作为一道模拟题这道题的细节很多……
输入
尽量不要一行直接一个字符串读完,例如“F i x y”类型的读入可以考虑先读入“F”,然后分别读入后面三个。
另外O(1)可以视作w=0。
中间信息的统计
用一个栈来统计中间出现过的循环。
读完题后可以发现每层循环的复杂度只有三种情况,三类情况可以分别用0、1、2存储:
0 不循环
1 常数
2 n
该操作的实现详见代码
判断ERR
显然可以直接用栈判断,然后一行是F语句时top++,E语句时top–,top–时判断一下是否合法即可,可以有一个bool变量来记录是否出现ERR,这样以后可以直接continue.
判断Yes/No
由于
L
<
=
100
L<=100
L<=100,显然可以考虑每次进入E语句时暴力枚举一下栈中所有元素的复杂度即可,注意当遇到未进入的循环(x>y)时直接break即可
代码:
#include<bits/stdc++.h>
#define re register
using namespace std;
const int n=100;
int T,L;
char O[10],op,i,x[5],y[5];
bool vis[26];
struct node{char var;int tim;}stk[101];
inline int get(char *s,int sum=0){
int re len=strlen(s);
for(int re tt=0;tt^len;++tt)sum=(sum<<1)+(sum<<3)+(s[tt]^48);
return sum;
}
inline int calc(int m){
int re ret=0;
for(int re tt=1;tt<=m;++tt){
ret+=(stk[tt].tim==2);
if(!stk[tt].tim)break;
}return ret;
}
signed main(){
scanf("%d",&T);
while(T--){
memset(vis,false,sizeof(vis));
int re w=0,ans=0,top=0;bool err=0;
scanf("\n%d%s",&L,O);
if(O[2]=='n')for(int re tt=4;isdigit(O[tt]);++tt)w=(w<<1)+(w<<3)+(O[tt]^48);
else w=0;
while(L--){
scanf("\n%c",&op);
if(op=='F'){
scanf(" %c%s%s",&i,x,y);
if(err)continue;
int re xx=0,yy=0;
if(x[0]=='n')xx=1;if(y[0]=='n')yy=1;
if(vis[i-'a']){err=1;continue;}
vis[i-'a']=1,stk[++top].var=i,stk[top].tim=yy-xx+1;
if(xx||yy)continue;
if(get(x)>get(y))stk[top].tim=0;
}
else{
if(!top)err=1;
if(err)continue;
ans=max(ans,calc(top)),vis[stk[top--].var-'a']=0;
}
}
if(top)err=1;
if(err){puts("ERR");continue;}
puts(ans==w?"Yes":"No");
}exit(0);
}