noip2017 时间复杂度

先吐槽

题目我就不贴了

很爆炸
当时考试的时候觉得很简单
然后就写啊写啊写
然后发现好多细节啊
emmm
然后 调大样例还是调了很久....然后就
哇 终于调过了!!!!!
一直觉得过了一个很强的样例 心里很安心

我tm len=strlen(s) 写成了 len-strlen(s) 都tm可以过样例
这就是菜过分的下场

Solution

学长是用函数递归写的 我觉得栈好写 就用栈了
无非麻烦一点就是 记录那个非法循环的时候 需要一点点小技巧
当存在非法循环 不更新答案

当然我代码还是很丑

#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream> 
#include <cstdio>
#include <stack>
#define maxn 2010
#define re register
using namespace std;

char ch[1010];
int ace,cnt,ans,tot;
bool err=false,instack[30];

stack<int>s,ss,sss;

inline int get_ace(){
    scanf("%s",ch+1);
    int st=3,rtn=0;
    if(isdigit(ch[st]))return 0;
    else st=5;
    while(isdigit(ch[st]))rtn=rtn*10+ch[st]-'0',st++; 
    return rtn;
}

inline int get_letter(){
    scanf("%s",ch+1);
    return ch[1]-'a';
}

inline int get_num(char *s){
    int st=1,rtn=0;
    while(isdigit(s[st]))rtn=rtn*10+s[st]-'0',st++;
    return rtn;
}

inline bool push_stack(){
    bool fail=false,isnum1=true,isnum2=true;
    int cur=get_letter(),num1,num2;
    if(instack[cur])fail=true;
    
    scanf("%s",ch+1);
    if(!isdigit(ch[1]))isnum1=false;
    if(isnum1)num1=get_num(ch);
    
    scanf("%s",ch+1);
    if(!isdigit(ch[1]))isnum2=false;
    if(isnum2)num2=get_num(ch);
    
    if(fail)return false;
    
    if((!isnum1&&isnum2)||((isnum1&&isnum2)&&(num1>num2))){
        s.push(cur);
        instack[cur]=true;
        ss.push(cnt);
        sss.push(-1);
        tot++;
    }
    
    if((isnum1&&isnum2)&&num1<=num2||(!isnum1&&!isnum2)){
        s.push(cur);
        instack[cur]=true;
        ss.push(cnt);
        sss.push(0);
    }
    
    if(isnum1&&!isnum2){
        s.push(cur);
        instack[cur]=true;
        ss.push(++cnt);
        sss.push(1);
    }
    return true;
}


inline bool pop_stack(){
    if(!s.size())return false;
    int cur=s.top();s.pop();
    instack[cur]=false;
    int pre_ans=ss.top();ss.pop();
    int flag=sss.top();sss.pop();
    if(flag==-1)tot--;
    else if(tot==0&&flag==0)ans=max(ans,pre_ans); 
    else if(tot==0&&flag==1)ans=max(ans,pre_ans),cnt--;
    else if(flag==1)cnt--;
    return true;
}

inline void pre_pare(){
    err=false;
    memset(instack,false,sizeof(instack));
    ans=cnt=tot=0;
    while(s.size())s.pop();
    while(ss.size())ss.pop();
    while(sss.size())sss.pop();
} 

int main(){
    freopen("in.txt","r",stdin);
    int T;scanf("%d",&T);
    while(T--){
        int n;scanf("%d",&n);
        ace=get_ace();
        pre_pare();
        for(int i=1;i<=n;i++){
            scanf("%s",ch+1);
            if(ch[1]=='F'){
                bool ok=push_stack();
                if(!ok)err=true;
            }
            else if(ch[1]=='E'){
                bool ok=pop_stack();
                if(!ok)err=true;
            }
        }
        if(s.size())err=true;
        if(err)printf("ERR\n");
        else if(ace==ans)printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

转载于:https://www.cnblogs.com/DexterYsw/p/7856512.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值