zoukankan      html  css  js  c++  java
  • 【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 } 

     

    隐约雷鸣,阴霾天空,但盼风雨来,能留你在此。

    隐约雷鸣,阴霾天空,即使天无雨,我亦留此地。

  • 相关阅读:
    WinRAR5.01注册码附注册机
    PS不能存储,因为程序错误
    mysql中 date datetime time timestamp 的区别
    sublime text 3 3126 注册码+中文包
    IIS7.5 用 IIS AppPool应用程序池名 做账号 将各站点权限分开
    linux vi 报错 E37: No write since last change (add ! to override)
    Linux 安装 apache2.4.23
    三级分类及名称及列表
    二级栏目名称及列表
    每隔N行输出不同样式
  • 原文地址:https://www.cnblogs.com/MisakaAzusa/p/8470118.html
Copyright © 2011-2022 走看看