【NOIP 2017 提高组 Day 1】时间复杂度——大模拟

这道题是noip题,你在哪个oj基本都能找到,这里就不给出题目大意了.

这道题我的思路就是输入之后,建一个栈来维护.

具体怎么维护,就是每次压入一个循环的时候,记录一下这次循环的各个信息.

我们维护信息只维护一个变量名,与一个省略过常数的时间复杂度.

省略过常数的时间复杂度只有三种情况:O(n),O(1)或O(0).

特别一说,若这一层为O(0),那么接下来的所有复杂度均为O(0).

然后我们只要遇到F入栈处理,遇到E就出栈.

那么每次入栈时,看前面一个的标记是什么(标记b为1是是O(n),为0是常数,为-1是O(0)),若是-1,这一层也是-1,否则跟上一层也没什么关系了.

所以代码大致如下:

#include<bits/stdc++.h>
  using namespace std;
#define rep(i,j,k) for (int i=j;i<=k;i++)      //专属神奇循环简写
struct stack{
  char c;
  int b;
}st[101];
bool b[101];
int top,T;
int tt;
bool flag=0;
string ss;
inline void start(){
  rep(i,0,100)
    st[i].c=EOF,st[i].b=0,b[i]=0;
  top=0;flag=0;
  tt=0;
  top=0;
}
inline void push(){
  int now=2;
  st[++top].c=ss[now];
  rep(i,1,top-1)
    if (st[i].c==ss[now]) flag=1;
  if (st[top-1].b==-1){
    st[top].b=-1;
    return;
  }
  int begin,end;
  now+=2;
  if (ss[now]=='n'){
    if (ss[now+2]=='n') st[top].b=0;
    else st[top].b=-1;
    return;
  }
  begin=ss[now]-'0';
  if (ss[now+1]<='9'&&ss[now+1]>='0') begin=begin*10+ss[now+1]-'0';
  while (ss[now]!=' ') now++;
  now++;
  if (ss[now]=='n'){
    st[top].b=1;
    b[++tt]=1;
    return;
  }else{
    end=ss[now]-'0';
    ss=ss+"  ";
    if (ss[now+1]<='9'&&ss[now+1]>='0')
      end=end*10+ss[now+1]-'0';
    if (end<begin) st[top].b=-1;
    else st[top].b=0;
    return;
  }
}
inline void pop(){
  if (st[top].b==1) tt--;
  st[top].b=0;
  top--;
}
inline void one(){
  getline(cin,ss);
  if (ss[0]=='F') push();
  else pop(); 
}
inline void work(){
  int l,time;
  cin>>T;
  rep(i,1,T){
    start();
    b[0]=1;
    cin>>l;
    getline(cin,ss);
    if (ss[3]=='1') time=0;
    else {
      time=ss[5]-'0';
      if (ss[6]<='9'&&ss[6]>='0')
        time=time*10+ss[6]-'0';
    }
    flag=0;
    rep(i,1,l) one();
    if (top||flag) {
      printf("ERR\n");
      continue;
    }
    if (b[time]&&!b[time+1]) printf("Yes\n");
    else printf("No\n");
  }
}
inline void outo(){
}
int main(){
  //into();
  work();
  //outo();
  return 0;
}

猜你喜欢

转载自blog.csdn.net/hzk_cpp/article/details/80285904