NOIp2017D1T2 时间复杂度【模拟】
说一说
题目分析请从目录空降...
没想到模拟题还会卡这么久...菜得真实...
这是一个励志的故事:从$0pts->9pts->18pts->27pts->36tps->54pts->72pts->84pts->100pts$
(还不是面向数据编程,虽然这个分数的变化看来很像...)

题目分析
非常明显的模拟题。
由$F$和$E$的匹配关系可以想到像括号匹配那样用栈来做。(其实之前没有想到用栈的,是想用一个$tot$变量来判断能不能匹配,但是后面发现要找层次关系,要找$E$对应的$F$是什么)
我的做法是在线的,给出的程序只扫了一遍(当然还是存下来以便后续读取),主要思路就是:
用栈来维护,遇到一个$F$就压进去,$tot++$,标记变量已经被使用,顺便判断变量重名;遇到一个$E$就弹栈,弹出来的就是和自己配对的$F$,清除变量名的标记,计算自己这一层的复杂度:
常数->常数 —— $0$
常数->$n$ —— $1$
$n$->$n$ —— $0$
$n$->常数 —— $0$
并更新统计答案。再说一下重点,统计答案:(不知道有没有雷同的,感觉自己的思路很清奇,不一定说得清楚qwq)
之前想过用递归写,因为时间复杂度是同层取$max$,不同层累计(外层的答案相当于是内层的最大值$+1/0$(外层计算出来的自己这一层的复杂度))。
$tot$表示层级,比如:

每一层循环都用$F$开始那个$tot$标号,就可以表示层级关系。
定义数组$ans[tot]$表示$tot$这一层的答案,在这一层需要干的事情就是更新$ans[tot]=max(ans[tot],ans[tot+1]+1/0$
然后要将$ans[tot+1]$赋为$0$,是为了同一层并列的情况。和这一层并列的循环不能使用当前循环的循环体内嵌套的循环来更新它(这句话好像有点绕...)因为这里是碰到$E$了,马上就要$tot--$,说明现在的$tot+1$是当前循环的内层循环,这个答案只能用来更新当前循环,而不能更新和当前循环并列的循环,而且进行到这一步说明内层循环已经没了,所以可以直接清成$0$。
注意有个特殊情况,就是外层循环根本就进不去,也就是$x>y$,这个时候这一层的答案是$0$,这里可以把$n$看成$INF$
最后计算出来的时间复杂度是$ans[1]$,把它和小明的答案进行比较就可以了。要注意小明的答案是用字符串读入的,而且有可能是个多位数,要转化成数字再和$ans[1]$比较。
遍历结束之后再看一下栈里面还有没有东西(或$tot>=0$),如果有,就$ERR$
判断$ERR$之后不要马上$break$,因为是多组数据而且是在线的,要把这组数据输入完,不然会影响后面数据的读入。
主要思路比较简单,但是细节有很多要处理,要小心。
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
#include<queue>
#include<map>
#include<iostream>
#include<stack>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
int rd()
{
int f=,s=;char c=getchar();
while(c<''||c>''){if(c=='-') f=-;c=getchar();}
while(c>=''&&c<=''){s=(s<<)+(s<<)+(c^);c=getchar();}
return f*s;
}
char /*cd[105][20],输入太怀疑人生了*/opt[];//不要在意这个名字(其实是因为懒得改了
bool vis[];
int ans[];
stack<int>s;
struct node{
string st,bl;
int ss,tt;
}cd[];
string t;
int main()
{
int T=rd();
while(T--)
{
memset(ans,,sizeof(ans));
memset(vis,,sizeof(vis));
int L=rd();
scanf("%s",opt+);
scanf("\n");
bool flag=;
int tot=;
for(int i=;i<=;i++)
cd[i].st="",cd[i].bl="",cd[i].ss=,cd[i].tt=;
for(int i=;i<=L;i++)
{
cin>>cd[i].st;
if(cd[i].st[]=='F')
{
cin>>cd[i].bl;
string t;cin>>t;
if(t=="n") cd[i].ss=INF;
else
{
for(int k=;k<t.size();k++)
cd[i].ss=cd[i].ss*+(t[k]-'');
}
cin>>t;
if(t=="n") cd[i].tt=INF;
else
{
for(int k=;k<t.size();k++)
cd[i].tt=cd[i].tt*+(t[k]-'');
}
tot++;
s.push(i);
if(vis[cd[i].bl[]-'a'])
flag=;
vis[cd[i].bl[]-'a']=;
}
if(cd[i].st[]=='E')
{
if(s.empty())
{//这里要用栈 实际上后面的tot<0就是在判这个东西 但是这里已经调用了栈 所以没用 会RE
flag=;
continue;//break;不能break啊 多组数据要影响输入
}
int k=s.top(),tmp=;s.pop();
vis[cd[k].bl[]-'a']=;
if(cd[k].ss!=INF&&cd[k].tt==INF) tmp=;
ans[tot]=max(ans[tot+]+tmp,ans[tot]);
ans[tot+]=;
//注意这里清空 后面tot会-- 这一层已经搞完了
//后面和这一层并列的东西不能从它的儿子部分得到
if(cd[k].ss>cd[k].tt) ans[tot]=;
tot--;
if(tot<)
{
flag=;
continue;//break;不能break啊 多组数据要影响输入
}
}
}
if(tot) flag=;
if(flag)
{
puts("ERR");
continue;
}
//printf("%d\n",ans[1]);
int res=;
int m=;
while(opt[m]>=''&&opt[m]<=''){res=res*+(opt[m]-'');m++;}
if(ans[]==&&opt[]=='') puts("Yes");
else if(ans[]==res) puts("Yes");
else puts("No");
}
return ;
}
Code
NOIp2017D1T2 时间复杂度【模拟】的更多相关文章
- luogu P3952 时间复杂度 模拟
题目链接 luogu P3952 时间复杂度 题解 直接模拟即可 注意不要直接return 我真是naive ...... 代码 #include<map> #include<sta ...
- 洛谷 - P3952 - 时间复杂度 - 模拟
https://www.luogu.org/problemnew/show/P3952 这个模拟,注意每次进入循环的时候把新状态全部入栈,退出循环的时候就退栈. 第一次就错在发现ERR退出太及时,把剩 ...
- 计蒜客 时间复杂度 (模拟) & 洛谷 P3952 时间复杂度
链接 : Here! 思路 : 这是一道大模拟, 区分好情况就没问题了 循环构成部分 : $F , x , i , j$ 和 $E$ , 需要注意的是 $i , j$, - 分析 $i, j$ 的情况 ...
- luoguP3952 [NOIP2017]时间复杂度 模拟
原本只是想看下多久能码完时间复杂度 然后在30min内就码完了,然后一A了???? 首先,这题完全可以离线做 我们先把所有的操作读完,判断合不合法之后,再去判断和标准答案的关系 具体而言 把所有的操作 ...
- 洛谷P3952 时间复杂度(模拟)
题意 题目链接 Sol 咕了一年的题解..就是个模拟吧 考场上写的递归也是醉了... 感觉一年自己进步了不少啊..面向数据编程的能力提高了不少 #include<bits/stdc++.h> ...
- [NOIP2017]时间复杂度(模拟)
sscanf读入数字,getline(cin,string)读一整行,其余暴力模拟即可. #include<cstdio> #include<string> #include& ...
- [NOIP2017] 时间复杂度 (模拟,栈)
题目链接 Solution 用栈进行模拟. 记录一个 \(map\) 来看循环变量有没有用过. 对于每一次入栈都加信息. 出栈直接将 \(top\) 减一下. 反正一堆乱七八糟的东西瞎搞... 注意条 ...
- NOIP 2017 时间复杂度 (模拟)
题目大意:略 傻了吧唧的我wa了好几次 我的模拟功底真的不咋地 linux下用gets会报错,我用的fgets #include <string> #include "stdio ...
- NOIP2010~2017部分真题总结
NOIP2010~2017部分真题总结 2010 (吐槽)md这个时候的联赛还只有4题吗? 引水入城 只要发现对于有合法解的地图,每个蓄水厂贡献一段区间这个结论就很好做了 那么\(O(n^3)\)对每 ...
随机推荐
- Java-判断是否为回文数
/** * @ClassName: IsPalindrome * @author: bilaisheng * @date: 2017年9月19日 下午2:54:08 * 判断是否为回文数 * true ...
- Java-Base64工具类
/* * Base64 encoding and decoding. * Copyright (C) 2001-2004 Stephen Ostermiller * http://ostermille ...
- LibreOffice/Calc:单元格设置下拉菜单
造冰箱的大熊猫,本文适用于LibreOffice Calc 5.1.6.2 + Ubuntu 16.04@cnblogs 2019/1/2 LibreOffice是一个类似Microsoft Off ...
- fileReader对象读取txt文件乱码问题 以及如何获取文件的url路径(绝对路径)
<input type="file" @change="aaa($event)"> <div id="hi">< ...
- 关于项目在网页中运行部分jsp出现乱码(由request.getRequestDispatcher("XXX.jsp").forward(request, response)造成)的解决方法
在写jsp的时候发现部分的jsp在浏览器预览时出现乱码,为一堆问号,如图: 当时问了同学,只有部分jsp会出现乱码,因为重新建一个jsp在运行就没有错误,可以显示出来,所以发现是jsp头部的错误,当新 ...
- python isinstance函数
isinstance是Python的一个内建函数 语法: 1 isinstance(object,classinfo) 如果参数object是classinfo的实例,或者object是classin ...
- Speed
传送门:Speed 题目大意 给一棵n个点的无根树,每条树边i给出li和ri表示速度在[li,ri]内才能通过这条边. 现在有m个询问,每个询问给出一个速度x,求以x的速度(不能改变)能在树上通过的路 ...
- LeetCode 106. 从中序与后序遍历序列构造二叉树(Construct Binary Tree from Inorder and Postorder Traversal)
题目描述 根据一棵树的中序遍历与后序遍历构造二叉树. 注意:你可以假设树中没有重复的元素. 例如,给出 中序遍历 inorder = [9,3,15,20,7] 后序遍历 postorder = [9 ...
- EBS GL 日记账行“账户说明”段说明显示不全
问题描述: 路径:总帐管理超级用户/日记帐/输入 如下图所示,日记账行的“账户说明字段”段值说明显示不全 解决方法: 路径:总帐管理超级用户/设置/财务系统/弹性域/关键字/段 如下图所示,找到相应的 ...
- ccf 201712-4 行车路线(70分)
ccf 201712-4 行车路线 解题思路: 首先Dijkstra是基于贪心算法的,即每一次作出的选择都具有贪心选择性.此题由于有“如果连续走小道,小明的疲劳值会快速增加,连续走s公里小明会增加s2 ...