[NOIp2017] 时间复杂度

NOIp 2017 D1T2 时间复杂度

洛谷 P3952 传送门

稍微压了压行,写到了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 }

 

转载于:https://www.cnblogs.com/eternhope/p/9720661.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值