• 洛谷【P3952】NOIP2017提高组Day1T2时间复杂度


    我对模拟的理解:http://www.cnblogs.com/AKMer/p/9064018.html

    题目传送门:https://www.luogu.org/problemnew/show/P3952

    作为一个在现场没有切出这题后来才(A)掉的弱鸡,我深感惭愧。

    主要是因为在(Day1T1)上浪费了太多时间,导致根本没有时间写这道模拟题————出考场后我是这样想的,我还以为要是有时间我就可以(440)了————所以(Day1T2)我爆零了。

    什么?你说这种水题我怎么还爆零?前(30)分不是送给我的吗?

    说起我爆零的原因都有些感到颜面扫地……作为八中的学生我居然没分清楚大小写。一看题目,瞬间被(ERR)吸引住了眼球,然后把(Yes)当作了(YES),把(No)当作了(NO)……

    但是今天我也花了1个多小时,在有数据的情况下才A掉,说明我的思维还是窄了点,想的不够全面。(440)不存在的,当初就算没看错大小写也就只有(370)……

    我们只需要用栈维护循环语句开头与结尾的匹配,并且维护“每个循环内的最高时间复杂度”就可以了。假设在最外面再套一个不存在的循环,那么该循环内的最高时间复杂度就是题目要求的答案。

    要注意一个循环内如果有多个互不干扰的循环,要用所有互不干扰的循环的复杂度取max更新当前循环的复杂度

    时间复杂度:(O(n));

    空间复杂度:(O(n));

    代码如下:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int inf=2e9;//把变量n当作inf
    
    int n,T;
    bool bo[30];//用来判断变量重名
    char tim[20];
    
    struct stence {
        int Max;//在此层循环内的时间复杂度最多是n^Max
        char opt[10],var[10],x[10],y[10];
    }sta[200],s[200];//我用栈模拟,所有语句提前全部读完,不然我用solve会GG
    
    int trans(char *a) {//将字符串转成数字
        if(a[1]=='n')return inf;
        int num=0,len=strlen(a+1);
        for(int i=1;i<=len;i++)
    		num=num*10+a[i]-'0';
        return num;
    }
    
    bool solve() {
        int top=0,Maxtim=0;
        for(int i=1;i<=n;i++) {
    		if(s[i].opt[1]=='F') {
    			if(bo[s[i].var[1]-'a'])return 0;
    			bo[s[i].var[1]-'a']=1;
    			sta[++top]=s[i];
    		}
    		else {
                if(!top)return 0;
                int a=trans(sta[top].x),b=trans(sta[top].y);
                bo[sta[top].var[1]-'a']=0;
                if(a>b)sta[top].Max=0;//不会进入当前循环
                if(a!=inf&&b==inf)sta[top-1].Max=max(sta[top-1].Max,sta[top].Max+1);
                else if(a<=b)sta[top-1].Max=max(sta[top-1].Max,sta[top].Max);//一定要记得写成a<=b而不是a<b,相等也是会进入循环的
                if(top==1)Maxtim=max(Maxtim,sta[0].Max);
                top--;
            }
        }
        if(top)return 0;
        if(Maxtim==0&&tim[3]=='1')puts("Yes");
        else {
            int num=0,len=strlen(tim+1);
            for(int i=5;i<len;i++)
                num=num*10+tim[i]-'0';
            if(num==Maxtim)puts("Yes");
            else puts("No");
        }//判断正确与否
        return 1;
    }
    
    int main() {
        scanf("%d",&T);
        while(T--) {
            scanf("%d%s",&n,tim+1);
            memset(bo,0,sizeof(bo));//clear
            sta[0].Max=0;//sta[0]是假设的不存在的最外层的循环,根据定义,sta[0].Max就是答案
            for(int i=1;i<=n;i++) {
                scanf("%s",s[i].opt+1);
                if(s[i].opt[1]=='F')
    				scanf("%s%s%s",s[i].var+1,s[i].x+1,s[i].y+1);
            }
            if(!solve())puts("ERR");
        }
        return 0;
    }
    
  • 相关阅读:
    idea注释模板配置
    component-scan中base-package包含通配符
    mysql查询datetime大于下午3点的数据
    Linux c 开发-4 使用QT远程调试Linux程序
    Linux c 开发-3 配置ubuntu子系统桌面环境
    Linux c 开发-2 配置Vs2019
    Linux c 开发-1 Ubuntu子系统18.04开启SSH
    STM32 例程-5 Proteus使用串口2
    STM32 例程-4 Proteus下串口发送数据
    STM32 例程-3 Proteus下单按键试验
  • 原文地址:https://www.cnblogs.com/AKMer/p/9073149.html
Copyright © 2020-2023  润新知