自认为是少有的复杂的代码
这题思想很简单,就是大模拟
对于for循环,一行读入4个字符串,然后分类讨论:
①:如果是一个正常的O(n),那么累计n的指数加1
②:如果是一个常数级别的,那么继续循环,但是不累计指数
③:如果这个循环是从n到常数,或大常数到小常数,那么这个循环及它内部的循环都不进,打好标记不要累计
④:至于如何防止变量的重复使用:将用过的变量放进栈里并打上标记,循环结束时出栈清标记即可
⑤:还要注意一些小细节:循环层数只计最深的一层,所以我们用一个累计变量cnt,每次结束循环考虑循环的情况:如果这个循环被累计了,cnt--,否则cnt不变,所以我们还要开一个栈,记录每个循环的情况(与存变量的栈同步使用即可)
剩下就好办了:
#include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #include <queue> #include <stack> using namespace std; char s[10]; char s1[10],s2[10]; char tt[10]; bool used[130]; int n; stack <char> Q; stack <int> M; int main() { scanf("%d",&n); while(n--) { int l; scanf("%d",&l); scanf("%s",tt); int flag=0; int flag0=0; int flag2=0; int cnt=0,maxcnt=0; memset(used,0,sizeof(used)); while(!M.empty()) { M.pop(); Q.pop(); } for(int i=1;i<=l;i++) { scanf("%s",s); if(flag0) { if(s[0]=='F') { scanf("%s",s); scanf("%s",s); scanf("%s",s); } continue; } if(s[0]=='E') { if(!flag) { flag0=1; continue; }else { char c=Q.top(); used[c]=0; Q.pop(); flag--; int y=M.top(); if(y==1) { cnt--; }else if(y==2) { flag2=0; } M.pop(); } }else { scanf("%s",s); if(used[s[0]]) { flag=1; scanf("%s",s); scanf("%s",s); continue; } used[s[0]]=1; Q.push(s[0]); scanf("%s",s1); scanf("%s",s2); flag++; if(s1[0]-'0'<=9&&s2[0]-'0'<=9&&s1[0]-'0'>=0&&s2[0]-'0'>=0) { int j=0; int x=0; while(s1[j]-'0'<=9&&s1[j]-'0'>=0) { x=x*10+s1[j]-'0'; j++; } int y=0; j=0; while(s2[j]-'0'<=9&&s2[j]-'0'>=0) { y=y*10+s2[j]-'0'; j++; } if(x>y) { flag2=1; M.push(2); }else { M.push(0); } continue; }else if(s2[0]-'0'<=9&&s2[0]-'0'>=0) { M.push(2); flag2=1; continue; }else { if(s2[0]=='n'&&s1[0]=='n') { M.push(0); continue; } if(!flag2) { cnt++; M.push(1); }else { M.push(0); } maxcnt=max(maxcnt,cnt); } } } if(flag) { flag0=1; } if(flag0) { printf("ERR "); continue; }else if(maxcnt==0&&tt[2]=='1') { printf("Yes "); continue; }else { int j=4; int x=0; while(tt[j]-'0'<=9&&tt[j]-'0'>=0) { x=x*10+tt[j]-'0'; j++; } if(x==maxcnt) { printf("Yes "); continue; } printf("No "); continue; } } return 0; }