NOIP2017TG D1T2 时间复杂度

题目链接

 

题意:

给出仅表示循环结构的简化语句,指出编译错误和时间复杂度。

 

程序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\n",&T);
    while(T--){
        scanf("%d O(%c",&L,&ch);
        if(ch=='1')
            w=0;
        else 
            scanf("^%d",&w);
        scanf(")\n");
        for(int i=1;i<=L;i++){
            scanf("%c",&ch);
            if(ch=='E'){
                str[i].f=false;
                scanf("\n");
                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("\n");
                
            }
            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\n");
            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\n");
        else 
            printf("No\n");
        
    }
    
    return 0;
    
}

 

小结:

$scanf$处理字符串熟练度$++$!

一个真实的故事:当年考联赛同队有人把$ERR$写成了$Err$结果怒爆$0$。

上一篇:2019各省省选试题选做


下一篇:fjwc2019 D1T2 (后缀自动机+dp)