【NOIP2017】day1 t2 时间复杂度

complexity

NOIP2017我认为最毒瘤的题。没有之一。

码农题,从去年难为我到现在。

给出一些tips。

①要先读入进来,再判断语法错误!!!
②在存循环类型时候,’F’用1表示,’E’用-1表示,这样你可以省不少力气。
③程序运行不到的地方,出现语法错误也是会报错的。特别注意变量的问题,都要判断进去。
④存n这个量的时候,用一个较大的数(比如13331),可以特别方便的判断。还是那句话,怎么方便怎么写,不然就乱了。
⑤当一个循环根本进入不了的时候,再次能体现出用±1来存循环类型的优越性。“运行”程序时开一个量temp,循环的一开始先判temp是否为0,为0说明目前循环很正常。反之,当前正处于skip阶段,改kh,continue即可。
⑥变量名不要随便起,会乱的。
⑦虽然数据范围小,也不能抱着瞎搞的心态!!!
⑧数据范围小,所以可以为了思路清晰,在函数里开一些非全局数组。(不是好习惯,但是因为100的size不会爆栈所以无所谓)
⑨代码其实不长,前提是不抱着瞎搞的心态。
#include <cstdio>
#include <cstring>
inline int max(int x, int y) {return (x > y) ? x : y;}
int T, n, exp; char str[20];
struct node {int cat, bl, l, r;}opt[110];
inline bool check() {
    int kh = 0;
    for(int i = 1; i <= n; ++i) {
        kh+= opt[i].cat;
        if(kh < 0) return false;
    }
    if(kh) return false;
    int used[26], sta[100], top = 0;
    memset(used, 0, sizeof(used));
    for(int i = 1; i <= n; ++i) {
        if(opt[i].cat == 1) {
            if(used[opt[i].bl]) return false;
            used[opt[i].bl] = 1;
            sta[++top] = opt[i].bl;
        }else used[sta[top--]] = 0;
    }
    return true;
}
inline int work() {
    int sta[110], top = 0, now = 0, ret = 0, kh = 0;
    for(int i = 1; i <= n; ++i) {
        if(kh) {kh+= opt[i].cat; continue;}
        if(opt[i].cat == 1) {
            if(opt[i].r < opt[i].l) {kh = 1; continue;}
            if(opt[i].r - opt[i].l + 1 > 200) ++now, sta[++top] = 13331;
            else sta[++top] = 1;
        }else {
            if(sta[top] > 200) --now;
            --top;
        }
        ret = max(ret, now);
    }
    return ret;
}
int main() {
    scanf("%d", &T);
    while(T--) {
        scanf("%d%s", &n, str);
        exp = (str[2] == 'n') ? (str[4] - '0') : (0);
        for(int i = 5; i < strlen(str) && '0' <= str[i] && str[i] <= '9'; ++i) exp = exp * 10 + str[i] - 48;
        for(int i = 1; i <= n; ++i) {
            char cat[5]; scanf("%s", cat);
            opt[i].cat = (cat[0] == 'F') ? (1) : (-1);
            if(cat[0] == 'F') {
                char bl = getchar();
                while(!('a' <= bl && bl <= 'z')) bl = getchar(); opt[i].bl = bl - 'a';
                char dgt[5]; scanf("%s", dgt);
                if(dgt[0] == 'n') opt[i].l = 13331;
                else {
                    int x = 0;
                    for(int j = 0; j < strlen(dgt); ++j) x = x * 10 + dgt[j] - 48;
                    opt[i].l = x;
                }
                scanf("%s", dgt);
                if(dgt[0] == 'n') opt[i].r = 13331;
                else {
                    int x = 0;
                    for(int j = 0; j < strlen(dgt); ++j) x = x * 10 + dgt[j] - 48;
                    opt[i].r = x;
                }
            }
        }
        if(!check()) {puts("ERR"); continue;}
        int ans = work();
        if(ans == exp) puts("Yes"); else puts("No");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值