首页 > 其他 > 详细

NOIP2017 时间复杂度

时间:2018-10-31 00:30:37      阅读:173      评论:0      收藏:0      [点我收藏+]

传送门

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

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

我们要处理以下事情:

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(‘\n‘)
#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\n");
      else (maxn == ctim) ? printf("Yes\n") : printf("No\n");
      while(sen < L)
      {
     cin >> s;
     if(s[0] == F) cin >> vari >> fir >> la;
     sen++;
      }
   }
   return 0;
}

 

NOIP2017 时间复杂度

原文:https://www.cnblogs.com/captain1/p/9880418.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!