题意:
给出仅表示循环结构的简化语句,指出编译错误和时间复杂度。
程序1(100pt):
字符串处理,字母数字夹杂,上$scanf$来做。注意到有复数种情况,各种空格空行要分类讨论清楚。
考虑同时查错和做复杂度,思考一下发现不行:出现不执行的循环体,查错要求进入,做复杂度要求跳过,不适合硬生生糅合在一起。
考虑先查错,再做复杂度。考虑到之后有跳过循环体的情况,查错时把同一对循环首尾做一个链接。
实现时,用栈来维护“层层深入,逐步退出”的数据关系。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define IL inline using namespace std; const int N=100; int L,w; bool num(char ch){ return '0'<=ch&&ch<='9'; } struct Txt{ bool f,f1,f2; //f:'F' f1:x==n f2:y==n char ch; int x,y; }str[N+3]; struct Stk{ char ch; int id; }stk[N+3]; bool vis['z'+3]; bool mrk[N+3]; int top,ans; int jmp[N+3]; int main(){ int T; char ch; scanf("%d ",&T); while(T--){ scanf("%d O(%c",&L,&ch); if(ch=='1') w=0; else scanf("^%d",&w); scanf(") "); for(int i=1;i<=L;i++){ scanf("%c",&ch); if(ch=='E'){ str[i].f=false; scanf(" "); continue; } str[i].f=true; scanf(" %c %c",&str[i].ch,&ch); if(ch=='n'){ str[i].f1=true; scanf("%c",&ch); } else { str[i].x=ch-'0'; str[i].f1=false; scanf("%c",&ch); while(num(ch)){ str[i].x=str[i].x*10+ch-'0'; scanf("%c",&ch); } } scanf("%c",&ch); if(ch=='n'){ str[i].f2=true; scanf(" "); } else { str[i].y=ch-'0'; str[i].f2=false; scanf("%c",&ch); while(num(ch)){ str[i].y=str[i].y*10+ch-'0'; scanf("%c",&ch); } } } bool flag=false; top=0; memset(vis,0,sizeof vis); for(int i=1;i<=L;i++) if(str[i].f){ if(vis[(int)str[i].ch]){ flag=true; break; } vis[(int)str[i].ch]=true; top++; stk[top].ch=str[i].ch; stk[top].id=i; } else { if(top==0){ flag=true; break; } vis[(int)str[stk[top].id].ch]=false; jmp[stk[top].id]=i; jmp[i]=stk[top].id; top--; } if(!flag&&top>0) flag=true; if(flag){ printf("ERR "); continue; } top=ans=0; memset(mrk,0,sizeof mrk); for(int i=1;i<=L;i++) if(str[i].f){ if(((!str[i].f1)&&(!str[i].f2) &&(str[i].x>str[i].y)) ||((str[i].f1)&&(!str[i].f2))){ i=jmp[i]; continue; } if((!str[i].f1)&&str[i].f2){ top++; mrk[i]=true; ans=max(ans,top); } } else if(mrk[jmp[i]]) top--; if(ans==w) printf("Yes "); else printf("No "); } return 0; }
小结:
$scanf$处理字符串熟练度$++$!
一个真实的故事:当年考联赛同队有人把$ERR$写成了$Err$结果怒爆$0$。