【luogu P3952 时间复杂度】 题解

对于2017 D1 T2 这道题

实实在在是个码力题,非常考验耐心。

其实大体的思路并不是非常难想出来,但是要注意的小细节比较多。

题目链接:https://www.luogu.org/problemnew/show/P3952

思路

对于每一个程序,先读入L和O(),并将其中的时间复杂度抠出来。

其次整行读入字符串,即所给定的程序。

判断第一个字符是F or E

F i x y 需要把x y拿出来,把i压进栈

E 退栈 压进i后为了方便退栈及退栈时判断,用一个flag标记

每做完一个程序,与前面抠出来的时间复杂度对比判断yesnoerr即可。

注意

1.我的readx和ready函数比较暴力,直接截取常数和n可能存在的位置并保存。所以在考虑情况时,常数与n的位置不能搞错,也不能少考虑。

2.在每搞完一个程序时,要把初始值和标记都初始化一遍。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <stack> 
  6 using namespace std;
  7 int L,t,anso,codeo;//anso=0 O(1)  anso=x O(n^x) 输入给的时间复杂度   codeo 自己算的时间复杂度  if anso==codeo yes else no     if codeo==-1 err
  8 string code[105];//按行输入所给代码(F,E)
  9 string ans;//读入给定的复杂度 O() 
 10 int readx(string x)
 11 {
 12     int num;
 13     if(x[4] >= '0' && x[4] <= '9') num = x[4]-'0';
 14     if(x[5] >= '0' && x[5] <= '9') num = (x[4]-'0')*10+x[5]-'0';
 15     if(x[4] == 'n') num = 1000000;
 16     return num;
 17 } //抠出给定的复杂度 x 
 18 int ready(string x)
 19 {
 20     int num;
 21     if(x[6] >= '0' && x[6] <= '9' && x[7] <= '0' || x[7] >= '9') num = x[6]-'0';
 22     if(x[7] >= '0' && x[7] <= '9' && x[8] <= '0' || x[8] >= '9') num = x[7]-'0';
 23     if(x[6] >= '0' && x[6] <= '9' && x[7] >= '0' && x[7] <= '9') num = (x[6]-'0')*10+x[7]-'0';
 24     if(x[7] >= '0' && x[7] <= '9' && x[8] >= '0' && x[8] <= '9') num = (x[7]-'0')*10+x[8]-'0';
 25     if(x[6] == 'n') num = 1000000;
 26     if(x[7] == 'n') num = 1000000;
 27     return num;
 28 }//抠出给定的复杂度 y 
 29 int check1()
 30 {
 31     int res;
 32     if(ans[2] == '1') res = 0;
 33         if(ans[2] == 'n')   
 34         {
 35             if(ans[4]<='9' && ans[4]>='0')
 36             res = ans[4]-'0';
 37             if(ans[5]<='9' && ans[5]>='0')
 38             res = (ans[4]-'0')*10 + ans[5]-'0';
 39         }//记录输入给的复杂度 
 40     return res;
 41 }
 42 int check2()
 43 {
 44         stack<int> s;
 45         int flag=-1;//标记 
 46         bool fe[26]={0};//上面都是便于栈操作,fe来记录变量名 
 47         int res=0,now=0;//now来记录当前循环中的时间复杂度,res是整个程序的时间复杂度 
 48         bool cflag[26]={0};//记录变量是否重复   0 则没用过    1 用过  changeflag
 49         int xnum,ynum;
 50 
 51     for(int i=1;i<=L;i++)
 52     {
 53 
 54         if(code[i][0]=='F')
 55         {       
 56             int k=code[i][2]-'a';
 57             if(cflag[k]) return -1;
 58             s.push(k);
 59             cflag[k] = 1;
 60 
 61             xnum=readx(code[i]); ynum=ready(code[i]);
 62             if(ynum-xnum>1000)
 63             {
 64                 if(flag==-1)
 65                 {
 66                     now++;
 67                     res=max(res,now); 
 68                     fe[k]=1;
 69                 }
 70             }
 71             if(xnum>ynum)
 72             {
 73                 if(flag==-1) flag=k;
 74             }
 75         }
 76 
 77         if(code[i][0]=='E')
 78         {
 79         if(s.empty()) return -1;
 80         int k=s.top();
 81         s.pop();cflag[k]=false;
 82         if(flag==k) flag=-1;
 83         if(fe[k]) 
 84             {
 85                 fe[k]=false;
 86                 now--;
 87             }
 88         }       
 89     }               
 90     if(s.size()) return -1;
 91     return res;
 92 }
 93 int main()
 94 {
 95     scanf("%d",&t);
 96     while(t--)
 97     {
 98 
 99         scanf("%d ",&L);getline(cin,ans);
100         anso=check1();
101 
102         for(int i=1;i<=L;i++)getline(cin,code[i]);
103         codeo=check2();
104 
105         if(codeo==-1) cout<<"ERR"<<endl;
106         else
107         {
108             if(anso!=codeo)  cout<<"No"<<endl;
109             if(anso==codeo)  cout<<"Yes"<<endl;
110         }
111     }
112     return 0;
113 } 

 

 

posted @ 2018-02-25 18:35  Misaka_Azusa  阅读(238)  评论(0编辑  收藏  举报
Live2D