【题解】洛谷P3952 [NOIP2017TG] 时间复杂度(模拟)

题目来源:洛谷P3952

思路

纯模拟没啥可说的了

果然好复杂

参考了你谷一个40行代码

代码

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int T,tot,num,Max,stand,now,k,n,cnt;
int member[30],what[110];
bool vis[30];
//tot是有几个句子,stand是题目给的复杂度是多少
//now是当前在几重循环,vis[]是判断变量是否使用过
//member[]是存下每个循环的变量,tot是当前复杂度是多少(与now不同)
//k是判断下面程序是否进行,what[]是存下哪几个循环加了复杂度
//m是当前最大复杂度,n是存下k=1时的循环数
//T是数据组数 
string a,b;//循环使用 
int main()
{
    cin>>T;
    while(T--)
    {
        Max=stand=tot=num=now=k=n=cnt=0;
        memset(vis,0,sizeof(vis));
        memset(what,0,sizeof(what));
        do
        {
            a=b;//记录一共有几行 
            cin>>b;
        }
        while(b[0]!='O');//当读入到O时停止一次 
        for(int i=0;i<a.length();i++) cnt=cnt*10+a[i]-'0';//计算有几行 
        for(int i=4;i<b.length()-1;i++) stand=stand*10+b[i]-'0';//计算是n的几次方 如果是O(1)不影响 存成0
        while(cnt--)
        {
            cin>>a;//输入第一个字符 
            if(a[0]=='F')
            {
                now++;//循环次数增加 
                cin>>a;//输入变量 
                if(vis[a[0]-96]) now=-1;//如果此变量已经用过 说明语法错误 
                else
                {
                    vis[a[0]-96]=1;
                    member[now]=a[0]-96;//记录在此次循环用了这个变量 
                }
                cin>>a>>b;//输入变量后面的两个数 
                if((a[0]!='n')&&(b[0]=='n')&&(!k))//如果前面是数字后面是n 且可以运行的话 
                {
                    tot++;//可行循环+1 
                    what[now]=1;//此循环有计算 
                }
                else if(((a.length()==b.length()&&a>b)||(a.length()>b.length())||(a[0]=='n'&&b[0]!='n'))&&(!k))
                {
                    //如果a>b(n 4,45 12,24 9) 而且可以运行 那么标记下面的都不能运行 记下当前循环 
                    //像5 8,76 78, n n 之类的不影响,不需要处理 
                    k=1;
                    n=now;
                }
            }
            else//跳出循环 
            {
                Max=max(Max,tot);//计算最大的循环次数 
                vis[member[now]]=0;//此变量被删去 
                if(what[now]==1)//如果此循环内增加了复杂度 
                {
                    what[now]=0;//清空标记 
                    tot--;//当前复杂度还原 
                }
                now--;//总循环还原 
                if(n>0&&now<n)//如果此时跳出了被n标记的循环 即不进行的循环 就把标记清楚 接下来的循环可以进行 
                {
                    k=0;
                    n=0;
                }
            }
            if(now==-1)//如果e<0(变量用过或者E过多),那么输出ERR,跳出循环 
            {
                cout<<"ERR"<<endl;
                break;
            }
        }
        if(now>0) cout<<"ERR"<<endl;//如果e>0(F过量),那么输出ERR,跳出循环
        if(now==0&&stand==Max) cout<<"Yes"<<endl;//如果F,E相同而且最大复杂度等于题目给的复杂度,输出Yes 
        if(now==0&&stand!=Max) cout<<"No"<<endl;//如果F,E相同而且最大复杂度不等于题目给的复杂度,输出No
    }
}

 

转载于:https://www.cnblogs.com/BrokenString/p/9873507.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值