[NOIp2017] luogu P3952 时间复杂度

时间:2023-03-10 01:44:00
[NOIp2017] luogu P3952 时间复杂度

跪着看评测很优秀。

题目描述

给你若干个程序,这些程序只有 For 循环,求这些程序的时间复杂度。

Solution

大模拟。讲下细节。

flag[i]flag[i]flag[i] 表示第 iii 位有没有对复杂度产生贡献,而且只有 F 开头的语句才会计算。

ed[i]ed[i]ed[i] 表示第 iii 位配套的 E 的位置(第 iii 位必须是 F)。

注意判 CE 的时候,

F x 2 1
F x 1 2
E
E

这个程序也要判 CE。



最后贴上代码

#include<cstdio>
#include<cstdlib>
#include<cstring> #define max(x,y) ((x)>(y)?(x):(y))
#define ERR() {puts("ERR");return;} int T;
int L,c;
char R[20];
int ans=0,now,h,cnt,cur;
char str[110][20];
int flag[110];
int x,y;
int st[110],ed[110];
bool bk[130]; int get(char*s,int t){
int l=strlen(s);
for(int i=0;i<l;++i){
if(s[i]==' ') --t;
if(!t){
if(s[i+1]=='n') return 101;
now=i;cnt=0;
do{
++now;
cnt=cnt*10+s[now]-'0';
}while(s[now+1]>='0'&&s[now+1]<='9');
return cnt;
}
}
}
int count(int l,int r){
if(ed[l]==r){
if(flag[l]==1) return count(l+1,r-1)+1;
else if(!flag[l]) return count(l+1,r-1);
return 0;
}
int sum=0;
for(int i=l;i<=r;i=ed[i]+1)
sum=max(sum,count(i,ed[i]));
return sum;
}
void work(){
ans=0;
if(R[3]=='1') ans=0;
else{
now=4;
do{
++now;
ans=ans*10+R[now]-'0';
}while(R[now+1]>='0'&&R[now+1]<='9');
}
for(int i=1;i<=L;++i){
x=get(str[i],2);y=get(str[i],3);
if(y==101&&x!=101&&str[i][0]=='F') flag[i]=1;
else if(x>y) flag[i]=-1;
else flag[i]=0;
}
memset(bk,0,sizeof(bk));
memset(st,0,sizeof(st));h=0;
memset(ed,0,sizeof(ed));
for(int i=1;i<=L;++i){
if(str[i][0]=='F'){
++h;
if(bk[str[i][2]]) {ERR();}
else bk[str[i][2]]=1;
st[h]=i;
}
else{
ed[st[h]]=i;
bk[str[st[h]][2]]=0;
--h;
}
if(h<0) ERR() ;
}
if(h) ERR();
puts((count(1,L)==ans)?"Yes":"No");
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%s",&L,R+1);
getchar();
for(int i=1;i<=L;++i)
gets(str[i]);
work();
}
}