NOIp 2017 D1T2 时间复杂度
稍微压了压行,写到了60行&&1.3kb以内,感觉自己的写法还是很清晰很优秀的。
少量的特判,比别的代码简洁多了。
时间复杂度转换成n的次数,O(1)则为0次。
t代表声明的复杂度,nt代表计算出的复杂度,最后判断是否相等。
首先每行每行读入,F就入栈,E就出栈不用多说。
用hash判断CE的情况。入栈出栈的时候同步修改h。
sz记录了F和E的差,如果运算过程中出现了负的sz或者sz的终值不为0,则CE。
把字符串转换成整数的算法类似读入优化。
如果一个循环不会被进入,就lock一下。
代表它之后的时间复杂度不会被更新。
lock代表该无效循环对应的栈中位置的深度。
出栈的时候就解除lock。
用一个tot[i]代表栈中从栈底开始连续i层数据的总时间复杂度。
如果新循环合法且复杂度为n、不为常数,那么新一层栈的tot为上一层的tot+1。
根据tot更新nt。
1 #include<cstdio> 2 #include<cstring> 3 4 int n,m,h[150],tot[105],tp,t; 5 char st[105]; 6 7 int main() 8 { 9 scanf("%d",&n); 10 while(n--) 11 { 12 memset(h,0,sizeof(h)); 13 memset(tot,0,sizeof(tot)); 14 scanf("%d",&m); 15 char ex[10]; 16 scanf("%s",ex+1); 17 t=tp=0; 18 if(ex[3]=='n') 19 for(int p=5;ex[p]!=')';p++)t=10*t+ex[p]-'0'; 20 int sz=0,er=0,nt=0,lock=0; 21 for(int i=1;i<=m;i++) 22 { 23 char op[5],nw[5],fr[5],to[5]; 24 scanf("%s",op+1); 25 if(op[1]=='E') 26 { 27 sz--; 28 if(tp==lock)lock=0; 29 if(sz<0)er=1; 30 else h[(int)(st[tp--])]=0; 31 continue; 32 } 33 sz++; 34 scanf("%s%s%s",nw+1,fr+1,to+1); 35 if(h[(int)(nw[1])]) 36 { 37 er=1; 38 continue; 39 } 40 h[(int)(nw[1])]=1; 41 st[++tp]=nw[1]; 42 tot[tp]=(fr[1]!='n'&&to[1]=='n'&&(!lock))?tot[tp-1]+1:tot[tp-1]; 43 if(fr[1]!='n'&&to[1]=='n'&&(!lock))nt=nt>tot[tp]?nt:tot[tp]; 44 int ff=0,tt=0; 45 if(fr[1]!='n') 46 for(int p=1;fr[p]>='0'&&fr[p]<='9';p++)ff=10*ff+fr[p]-'0'; 47 if(to[1]!='n') 48 for(int p=1;to[p]>='0'&&to[p]<='9';p++)tt=10*tt+to[p]-'0'; 49 if(fr[1]=='n'&&to[1]!='n')lock=tp; 50 if(fr[1]!='n'&&to[1]!='n'&&(ff>tt))lock=tp; 51 } 52 if(er||(sz!=0))printf("ERR\n"); 53 else if(nt==t)printf("Yes\n"); 54 else printf("No\n"); 55 } 56 return 0; 57 }