NOIP2017 D1T2时间复杂度
这道题在考试时看到感觉与第一题放反了位置(因为我还没有看到第一题是结论题)
对于每个语句进行栈的模拟,而如果有语法错误就特判。
对于每一条for语句我们将其与栈顶元素连边,复杂度是1的我们不用考虑,如果复杂度是n我们就算他的贡献加一。
这样我们求最大复杂度就相当于求一颗子树的最大深度,当然如果这条语句不合法我们就将其整颗子树贡献算为0。
1 #include<bits/stdc++.h> 2 using namespace std; 3 int top; 4 struct node 5 { 6 int to,nex; 7 }e[1000005]; 8 int cnt,head[10005]; 9 void add(int x,int y) 10 { 11 e[++cnt].to=y;e[cnt].nex=head[x];head[x]=cnt; 12 } 13 int inf=1e9; 14 struct poin 15 { 16 int l,r,id; 17 }a[100005]; 18 stack<poin>qq; 19 int dfs(int x) 20 { 21 int pre=0; 22 int ma=0; 23 if(a[x].l!=inf&&a[x].r==inf)pre=1; 24 if(a[x].l>a[x].r)return 0; 25 for(int i=head[x];i;i=e[i].nex) 26 { 27 ma=max(ma,dfs(e[i].to)); 28 } 29 return ma+pre; 30 } 31 char s[100]; 32 bool b[10000]; 33 int q[10005]; 34 int main() 35 { 36 int t,n; 37 scanf("%d",&t); 38 while(t--) 39 { 40 cnt=0; 41 memset(head,0,sizeof(head)); 42 memset(b,0,sizeof(b)); 43 memset(q,0,sizeof(q)); 44 scanf("%d",&n);top=0;while(!qq.empty())qq.pop(); 45 scanf("%s",s);int x=0;bool flag=0; 46 if(s[2]>='0'&&s[2]<='9') 47 for(int i=2;s[i]>='0'&&s[i]<='9';++i) 48 x=x*10+s[i]-'0'; 49 else{ 50 for(int i=4;s[i]>='0'&&s[i]<='9';++i) 51 x=x*10+s[i]-'0'; 52 } 53 if(s[2]!='n')x=0; 54 for(int i=1;i<=n;++i) 55 { 56 scanf("%s",&s); 57 if(s[0]=='F') 58 { 59 scanf("%s",&s);int d=s[0]-'a'+1; 60 if(b[d]){ 61 flag=1; 62 }int u=0,v=0;int w=0,z=0; 63 b[d]=1;q[++top]=d; 64 scanf("%s",&s); 65 if(s[0]=='n')w=inf; 66 else{while(s[u]>='0'&&s[u]<='9')w=w*10+s[u]-'0',++u;} 67 scanf("%s",&s); 68 if(s[0]=='n')z=inf; 69 else{while(s[v]>='0'&&s[v]<='9')z=z*10+s[v]-'0',++v;} 70 a[i].l=w;a[i].r=z;a[i].id=i; 71 72 73 if(qq.empty()) 74 add(0,i); 75 else add(qq.top().id,i); 76 qq.push(a[i]); 77 78 } 79 else 80 { 81 if(qq.empty())flag=1; 82 else{b[q[top]]=0;--top;qq.pop();} 83 } 84 } 85 if(!qq.empty())flag=1; 86 if(flag){ 87 puts("ERR");continue; 88 } 89 int ans=dfs(0); 90 if(ans!=x)puts("No"); 91 else puts("Yes"); 92 } 93 return 0; 94 } 95
考试时我没有求max而是算的sum
还好noip数据水让我混了90分,谢天谢地。
生命中真正重要的不是你遭遇了什么,而是你记住了哪些事,又是如何铭记的。