zoukankan      html  css  js  c++  java
  • NOIP2017 时间复杂度

    传送门

    这道题我去年做到爆炸,最后还是爆零了,现在我还是特别慢才写完……

    唯一不同就是现在思路比较清晰,但是我的做法比较复杂,代码很长。

    我们要处理以下事情:

    1.读入程序行数,得到该程序时间复杂度。

    这个很简单,我的方法是写一个函数判断一下,然后返回当前时间,如果是常数级就是0.

    2.读入程序,判断是否合法。

    这一步判断只需要判断变量是否重复即可,不合法直接退出。

    3.判断能否进入这次循环。

    因为scanf遇到空格会停下,所以我直接使用string来处理。我们要处理的其实就是一个数和n,我写了一个函数进行判断。

    4.如果不能进入循环,进入查错状态。

    如果不能循环,那么里面的代码没什么用,只能查错。这个还是很舒服的,因为里面就不用考虑能不能进入循环,只考虑是否合法即可。还是自写了一个函数进行判断,只判断变量名重复。之后如果当前栈顶比进来的时候还少,那就从查错状态中返回。

    5.能进入循环,进行压栈,更新答案。

    这个不用多说了,注意每次的时间也要压入栈中,否则因为我是在线处理的,循环结束的时候你不知道自己应不应该减时间。注意每次压栈都要更新一次当前的最大复杂度。

    6.判断循环结束。

    这个也很简单,每次把栈还原即可。

    7.判断合法。

    如果程序结束的时候栈中还有元素或栈中无元素还在往外弹,那就不合法。

    注意因为我的方法是直接跳出,所以即使程序不合法也要全部读完。

    8.输出结果。

    其他注意事项是注意每次保险起见清空数组,之后要记录当前读到哪了,查错和普通状态下都要++。

    感觉自己临近NOIP码力仍然很弱……时间不多了。

    看一下代码。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    #define enter putchar('
    ')
    #define pr pair<int,int>
    #define mp make_pair
    #define fi first
    #define sc second
    using namespace std;
    typedef long long ll;
    const int M = 100005;
    const int N = 10000005;
     
    int read()
    {
       int ans = 0,op = 1;
       char ch = getchar();
       while(ch < '0' || ch > '9')
       {
          if(ch == '-') op = -1;
          ch = getchar();
       }
       while(ch >='0' && ch <= '9')
       {
          ans *= 10;
          ans += ch - '0';
          ch = getchar();
       }
       return ans * op;
    }
    
    int T,L,sta[1005],top,maxn,maxt,csta[1005],ctop,sen;
    bool vis[105];
    string s,vari,fir,la;
    
    void clear()
    {
       memset(sta,0,sizeof(sta)),top = 0;
       memset(csta,0,sizeof(csta)),ctop = 0;
       memset(vis,0,sizeof(vis)),maxn = sen = 0;
    }
    
    int caltime()
    {
       if(s[2] == '1') return 0;
       int k = 4,cur = 0;
       while(s[k] >= '0' && s[k] <= '9') cur *= 10,cur += s[k] - '0',k++;
       return cur;
    }
    
    bool illegal()
    {
       return vis[vari[0] - 'a' + 1];
    }
    
    bool in()
    {
       if(fir[0] == 'n') return la[0] == 'n';
       int cur = 0,cur1 = 0;
       rep(i,0,fir.length()-1) cur *= 10,cur += fir[i] - '0';
       if(la[0] == 'n') return 1;
       rep(i,0,la.length()-1) cur1 *= 10,cur1 += la[i] - '0';
       return cur < cur1;
    }
    
    bool addtime()
    {
       if(fir[0] == 'n') return 0;
       return la[0] == 'n';
    }
    
    bool check()
    {
       int d = top;
       while(1)
       {
          sen++;
          cin >> s;
          if(s[0] == 'F')
          {
         cin >> vari >> fir >> la; 
         if(illegal()) return 0;
         else sta[++top] = vari[0] - 'a' + 1,vis[sta[top]] = 1;
          }
          else if(s[0] == 'E')
          {
         vis[sta[top]] = 0,sta[top--] = 0;
         if(top == d - 1) return 1;
          }
       }
    }
    
    bool solve(int L,int ctim)
    {
       int maxt = maxn = 0;
       while(sen < L)
       {
          sen++,cin >> s;
          if(s[0] == 'F')
          {
         cin >> vari >> fir >> la;
         if(illegal()) return 0;
         if(!in())
         {
            sta[++top] = vari[0] - 'a' + 1,vis[sta[top]] = 1;
            if(!check()) return 0;
         }
         else
         {
            sta[++top] = vari[0] - 'a' + 1,vis[sta[top]] = 1;
            csta[++ctop] = maxt,maxt += addtime();
            maxn = max(maxn,maxt);
         }
          }
          else
          {
         if(!top) return 0;
         vis[sta[top]] = 0,sta[top--] = 0,maxt = csta[ctop--];
          }
       }
       if(top) return 0;
       return 1;
    }
    
    int main()
    {
       T = read();
       while(T--)
       {
          clear();
          L = read(),cin >> s;
          int ctim = caltime();
          if(!solve(L,ctim)) printf("ERR
    ");
          else (maxn == ctim) ? printf("Yes
    ") : printf("No
    ");
          while(sen < L)
          {
         cin >> s;
         if(s[0] == 'F') cin >> vari >> fir >> la;
         sen++;
          }
       }
       return 0;
    }
  • 相关阅读:
    background-position-x和background-position-y的兼容性问题
    用SVGDeveloper制作svg地图
    实现绝对定位元素水平垂直居中的两种方法
    用-webkit-box-reflect制作倒影
    解决ul的li横向排列换行的问题
    用echarts.js制作中国地图,点击对应的省市链接到指定页面
    css3制作扇形菜单
    IE7中a标签包含img,点击img,链接失效的bug
    ie7中position:fixed定位后导致margin:0 auto;无效
    背景图片铺满全屏的方法
  • 原文地址:https://www.cnblogs.com/captain1/p/9880418.html
Copyright © 2011-2022 走看看