题解:
好恶心的模拟题…调了一晚上…
题意让我们模拟循环,同时判断语法是否有误,并计算时间复杂度是否一致
首先考虑有没有语法错误:
我们先将’n’置于一个比较大的数字,flag=-1;
利用一个栈S,遍历一遍代码,如果是F,则记录变量名,将k进栈。
1.如果b>a,那么没有进入循环,用一个flag保存最早的没有进入的下标k,mark标记
2.如果a≤b,代表进入循环,那么判断循环上下限是否>200并且flag是否为-1,若都满足,说明本层循环是有贡献的,那么让当前的循环层+1,
如果返回时遇到了最初没有进入循环的k,我们将它的mark消除即可
如果是E,那么同样要记录变量名,将变量名k弹出,同时判断flag是否等于当前k,如果是,则表示已经出了没有贡献的循环,再判断当前k是否对复杂度有贡献即可
最后判断栈S是否为空(类似于括号匹配),不为空,同样返回“ERR”
最后返回语法正确的时间复杂度,判断即可
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 105;
string op[MAXN],ss;
bool vis[30],mark[30]; int n;
inline int Int(int &x,string s){
int res=0,len=s.size();
while(s[x]<'0' || s[x]>'9' && x<s.size()){
if(s[x]=='n') { ++x;return 100000; }
++x;
}
while(s[x]>='0' && s[x]<='9') res=res*10+s[x]-'0',++x;
return res;
}
inline int get(){
int res=0,x=3,len=ss.size();
if(ss[2]=='n') return Int(x,ss);
else return 0;
}
inline int solve(){
int res=0,now=0,a,b,x,flag=-1;
stack<int> s;
memset(vis,0,sizeof(vis)); memset(mark,0,sizeof(mark));
for(int i=1;i<=n;i++){
if(op[i][0]=='F'){
int p=op[i][2]-'a';
if(vis[p]) return -1;
s.push(p); vis[p]=true; x=4;
a=Int(x,op[i]); b=Int(x,op[i]);
if(b-a>1000){
if(flag==-1) { now++; res=max(res,now); mark[p]=true; }
}
if(a>b && flag==-1) flag=p;
}else if(op[i][0]=='E'){
if(s.empty()) return -1;
int k=s.top(); s.pop();
vis[k]=false;
if(flag==k) flag=-1;
if(mark[k]) { mark[k]=false; now--; }
}
}
if(s.size()) return -1;
return res;
}
int main(){
//freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);
int T; scanf("%d",&T);
while(T--){
scanf("%d ",&n); getline(cin,ss);
int tag = get();
for(int i=1;i<=n;i++) getline(cin,op[i]);
int ans=solve();
if(ans==-1) puts("ERR");
else if(ans==tag) puts("Yes");
else puts("No");
}
return 0;
}