NOIp2017D1T2 时间复杂度【模拟】
说一说
题目分析请从目录空降...
没想到模拟题还会卡这么久...菜得真实...
这是一个励志的故事:从
(还不是面向数据编程,虽然这个分数的变化看来很像...)
题目分析
非常明显的模拟题。
由和的匹配关系可以想到像括号匹配那样用栈来做。(其实之前没有想到用栈的,是想用一个变量来判断能不能匹配,但是后面发现要找层次关系,要找对应的是什么)
我的做法是在线的,给出的程序只扫了一遍(当然还是存下来以便后续读取),主要思路就是:
用栈来维护,遇到一个就压进去,,标记变量已经被使用,顺便判断变量重名;遇到一个就弹栈,弹出来的就是和自己配对的,清除变量名的标记,计算自己这一层的复杂度:
常数->常数 ——
常数-> ——
-> ——
->常数 ——
并更新统计答案。再说一下重点,统计答案:(不知道有没有雷同的,感觉自己的思路很清奇,不一定说得清楚qwq)
之前想过用递归写,因为时间复杂度是同层取,不同层累计(外层的答案相当于是内层的最大值(外层计算出来的自己这一层的复杂度))。
表示层级,比如:
每一层循环都用开始那个标号,就可以表示层级关系。
定义数组表示这一层的答案,在这一层需要干的事情就是更新
然后要将赋为,是为了同一层并列的情况。和这一层并列的循环不能使用当前循环的循环体内嵌套的循环来更新它(这句话好像有点绕...)因为这里是碰到了,马上就要,说明现在的是当前循环的内层循环,这个答案只能用来更新当前循环,而不能更新和当前循环并列的循环,而且进行到这一步说明内层循环已经没了,所以可以直接清成。
注意有个特殊情况,就是外层循环根本就进不去,也就是,这个时候这一层的答案是,这里可以把看成
最后计算出来的时间复杂度是,把它和小明的答案进行比较就可以了。要注意小明的答案是用字符串读入的,而且有可能是个多位数,要转化成数字再和比较。
遍历结束之后再看一下栈里面还有没有东西(或),如果有,就
判断之后不要马上,因为是多组数据而且是在线的,要把这组数据输入完,不然会影响后面数据的读入。
主要思路比较简单,但是细节有很多要处理,要小心。

1 #include<cstdio> 2 #include<algorithm> 3 #include<vector> 4 #include<cstring> 5 #include<queue> 6 #include<map> 7 #include<iostream> 8 #include<stack> 9 using namespace std; 10 #define ll long long 11 #define INF 0x3f3f3f3f 12 int rd() 13 { 14 int f=1,s=0;char c=getchar(); 15 while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();} 16 while(c>='0'&&c<='9'){s=(s<<3)+(s<<1)+(c^48);c=getchar();} 17 return f*s; 18 } 19 char /*cd[105][20],输入太怀疑人生了*/opt[10];//不要在意这个名字(其实是因为懒得改了 20 bool vis[30]; 21 int ans[105]; 22 stack<int>s; 23 struct node{ 24 string st,bl; 25 int ss,tt; 26 }cd[105]; 27 string t; 28 int main() 29 { 30 int T=rd(); 31 while(T--) 32 { 33 memset(ans,0,sizeof(ans)); 34 memset(vis,0,sizeof(vis)); 35 int L=rd(); 36 scanf("%s",opt+1); 37 scanf("\n"); 38 bool flag=0; 39 int tot=0; 40 for(int i=1;i<=101;i++) 41 cd[i].st="",cd[i].bl="",cd[i].ss=0,cd[i].tt=0; 42 for(int i=1;i<=L;i++) 43 { 44 cin>>cd[i].st; 45 if(cd[i].st[0]=='F') 46 { 47 cin>>cd[i].bl; 48 string t;cin>>t; 49 if(t=="n") cd[i].ss=INF; 50 else 51 { 52 for(int k=0;k<t.size();k++) 53 cd[i].ss=cd[i].ss*10+(t[k]-'0'); 54 } 55 cin>>t; 56 if(t=="n") cd[i].tt=INF; 57 else 58 { 59 for(int k=0;k<t.size();k++) 60 cd[i].tt=cd[i].tt*10+(t[k]-'0'); 61 } 62 tot++; 63 s.push(i); 64 if(vis[cd[i].bl[0]-'a']) 65 flag=1; 66 vis[cd[i].bl[0]-'a']=1; 67 } 68 if(cd[i].st[0]=='E') 69 { 70 if(s.empty()) 71 {//这里要用栈 实际上后面的tot<0就是在判这个东西 但是这里已经调用了栈 所以没用 会RE 72 flag=1; 73 continue;//break;不能break啊 多组数据要影响输入 74 } 75 int k=s.top(),tmp=0;s.pop(); 76 vis[cd[k].bl[0]-'a']=0; 77 if(cd[k].ss!=INF&&cd[k].tt==INF) tmp=1; 78 ans[tot]=max(ans[tot+1]+tmp,ans[tot]); 79 ans[tot+1]=0; 80 //注意这里清空 后面tot会-- 这一层已经搞完了 81 //后面和这一层并列的东西不能从它的儿子部分得到 82 if(cd[k].ss>cd[k].tt) ans[tot]=0; 83 tot--; 84 if(tot<0) 85 { 86 flag=1; 87 continue;//break;不能break啊 多组数据要影响输入 88 } 89 } 90 } 91 if(tot) flag=1; 92 if(flag) 93 { 94 puts("ERR"); 95 continue; 96 } 97 //printf("%d\n",ans[1]); 98 int res=0; 99 int m=5; 100 while(opt[m]>='0'&&opt[m]<='9'){res=res*10+(opt[m]-'0');m++;} 101 if(ans[1]==0&&opt[3]=='1') puts("Yes"); 102 else if(ans[1]==res) puts("Yes"); 103 else puts("No"); 104 } 105 return 0; 106 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现