NOIP 2017 Day1 T2 时间复杂度

luogu题面

大模拟...并不难(然而考场上写挂了)

3 个读入函数,解决读入问题

双栈齐发,一个记录使用过的字母,另一个记录复杂度贡献情况

bre 表示当前跳出循环的层数

err 表示当前编译状态是否编译失败

sans 分别表示当前复杂度总复杂度

那么当读取到 ‘F‘ 时,我们就要做以下几点

  1. 读取循环中使用的字母,并判断其是否被使用过,并将其标记为已使用;
  2. 读取循环的起止值,判断其能否被进入,并且处理好跳出循环的层数;
  3. 判断该循环对复杂度的贡献情况,处理好 s 和 ans ;

当读取到 ‘E’ 时要做以下几点

  1. 弹出两栈栈顶元素,将弹出的变量销毁;
  2. 处理好编译错误的情况和循环的跳出层数;

代码短小精干(1kb),通俗易懂:

#include<bits/stdc++.h>using namespace std;
bool use[256];
stack<char>q;  // 记录循环变量stack<int>p;  // 记录循环对复杂度的贡献情况
inline int getnum(){  // 读取下一个数字
    char ch=getchar();
    int x=0;
    while((ch<‘0‘||ch>‘9‘)&&ch!=‘n‘) ch=getchar();  // 除了‘n‘,别的都无脑跳过
    if(ch==‘n‘) return 100;  // 数字最大 99,设 n == 100 方便处理
    while(ch>=‘0‘&&ch<=‘9‘) x=x*10-48+ch,ch=getchar();
    return x;
}
inline char get(){  // 读取下一个字符(非空格和回车)
    char ch=getchar();
    while(ch==‘ ‘||ch==‘\n‘) ch=getchar();
    return ch;
}
inline int getn(){  // 判断能否读取到‘n‘(感觉好多余啊)
    if(getnum()==100) return 1;
    return 0;
}
int main(){
    int t=getnum();
    while(t--){
        memset(use,0,sizeof(use));  // 初始化
        int n=getnum(),f=getn(),err=0,s=0,bre=0,ans=0,ch;  // 一堆变量
        if(f) f=getnum();  // f 表示复杂度的指数(这两行的读入很精髓哦)
        while(n--)
            if(get()==‘F‘){  // 开始乱搞...
                q.push(ch=get());
                if(use[ch]) err=1;
                use[ch]=1;  // 以上三行处理变量
                int l=getnum(),r=getnum();
                if(l>r||bre) bre++;  // 自行体会对于跳出层数的处理
                if(l<r&&r==100&&!bre) s++,p.push(1),ans=max(s,ans);  // 对复杂度产生 1 贡献
                else p.push(0);  // 没有贡献
            }
            else{
                if(!p.empty()) s-=p.top(),use[q.top()]=0,p.pop(),q.pop();  // 各种操作(压行大法好)
                else err=1;
                if(bre) bre--;
            }
        while(!q.empty()) err=1,q.pop(),p.pop();  // 将栈弹空(如果栈非空则编译错误)
        printf(err?"ERR\n":ans==f?"Yes\n":"No\n");  // 三目运算符简化代码(懒...)
    }
    return 0;  // ......
}

By The_Seventh

2017-12-24  09:23:53

时间: 2024-10-08 02:46:50

NOIP 2017 Day1 T2 时间复杂度的相关文章

NOIP 2016 Day1 T2 天天爱跑步

题目大意 给定一个n个节点,n?1条边的树.有m个玩家,第i个玩家从xi走树上最短路径到yi.玩家第0秒在自己的起点上,然后每秒移动一条边,移动到终点后结束移动. 每个节点上有一个观察员以及权值wi.如果有一个玩家在其移动的第wi秒恰好到达这个点,那么这个点上的观察员就会观察到他(如果这个点是终点,且玩家在wi秒之前到达不算). 求每个点上的观察员分别观察到了多少个玩家. 1≤n≤299998,1≤m≤299998 题目分析 我们将每条路径拆成从出发点到lca,和从lca的下一个点到结束点两段.

NOIP 2011 Day1 T2 选择客栈

1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<string> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #include<stack> 10 #include<iomanip>

NOIP 2017 Day1 T1 小凯的疑惑

luogu题面 小学奥数呵呵 在考场上40分钟没证出来(数学太差),运气好看到了规律... 来一波证明: 定义 f(a,b) 表示在 gcd(a,b)==1 情况下的答案. 贝祖定理 易证:对于 gcd(c,b)==1,c > a , 有 f(c,b) = f(a,b) + (c-a)*(b-1) 因为我们已知:f(a,b) == f(b,a) ,且 gcd(a,b) == 1 那么我们不妨令 b 为奇数(两数至少一数为奇数) 那么,f(a,b) == f(2,b) + (a-2)*(b-1)

#6030. 【雅礼集训 2017 Day1】矩阵

#6030. 「雅礼集训 2017 Day1」矩阵 题目描述 有一个 n×n  的矩阵,每个位置 (i,j) 如果是 . 表示为白色,如果是 # 表示为黑色. 初始时,每个位置可以是黑色或白色的,(i,j)  位置的值会作为 ai,j 给你. 现在有一种操作,选择两个整数 i,j∈[1,n],记 (i,1),(i,2),…,(i,n) (i, 1), (i, 2)的颜色为 C1,C2,…Cn ??,将 (1,j),(2,j),…,(n,j)  的颜色赋为 C1,C2,…,Cn ??. 你的任务是

NOIp 2013 Day1 解题报告

NOIp 2013 Day1 解题报告 1.   转圈游戏 不难看出答案就是(x+m*10k) mod n 用快速幂算法,复杂度O(log2k) 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 8 //variable// 9 int n,m,x,

NOIP 2012 提高组 DAY1 T2 国王游戏

题目描述 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右 手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排 成一排,国王站在队伍的最前面.排好队后,所有的大臣都会获得国王奖赏的若干金币,每 位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右 手上的数,然后向下取整得到的结果. 国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序, 使得获得奖赏最多的大臣,所获奖赏尽可能的少

2017 9 11 noip模拟赛T2

#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=205; int map[N][N]; int d[N],tag[N],book[N],f[N]; int n,m; void work(int x) { memset(d,63,sizeof(d)); memset(book,0,sizeof(book)); memset(f,0,sizeof(

【NOIP之旅】NOIP2014 day1 T2 联合权值

2.联合权值 (link.cpp/c/pas) [问题描述] 无向连通图G有n个点,n-1条边.点从1到n依次编号,编号为i的点的权值为Wi  ,每条边的长度均为1.图上两点(u, v)的距离定义为u点到v点的最短距离.对于图G上的点对(u, v),若它们的距离为2,则它们之间会产生Wu×Wv的联合权值. 请问图G上所有可产生联合权值的有序点对中,联合权值最大的是多少?所有联合权值之和是多少? [输入] 输入文件名为link.in. 第一行包含1个整数n. 接下来n-1行,每行包含2个用空格隔开

[日常] NOIP 2017滚粗记

突然挑了这么个滑稽的时间补了游记... (成绩日常延时再加上人太菜估计基本上就是颓废记录) 然而文化课太废可能会被强制退役QAQ所以先补了再说吧 day0 一大早被老姚交代了个开十一机房门的任务... 打开门之后本来想去高二那边后来一想还是自己慢慢乱搞比较好... 然后就和高一混在一起 前一天晚上和母上谈了谈然后成功把笔电带上了(233333333) 早上的时候发现 $794$ 势力似乎并没有收拾东西...窝就让他们去找阔少去开条了 于是乎他们两个被批了一顿回来了(后来发现并没必要) 后来 8: