5 条题解
-
3
LJFan LV 9 @ 7 年前
用栈模拟,模拟时记下所有未被销毁的名字集合,以及当前层的复杂度的维数。
F i x y中,
若x=c1,y=c2,c1<=c2,维数为0
若x=c1,y=c2,c1>c2,维数为-inf(循环不执行)
若x=c1,y=n,维数为1
若x=n,y=c2,维数为-inf(循环不执行)
若x=y=n,维数为0作者:NiroBC大姐姐
链接:https://www.zhihu.com/question/67960571/answer/258225928
来源:知乎 -
15 年前@
#include <bits/stdc++.h>
#define in inline
#define re register
#define N 1005
using namespace std;
int pos=0,cnt=0,tot=0,num=0,T,L,ans,st[N];
/* pos表示如果在某处的循环是不执行的 那么 它的嵌套也是无效的
cnt记录复杂度,只负责记录n^ 的复杂度 表示当前的时间复杂度
tot表示给出的整个程序中的最大复杂度 即程序的复杂度
num当前是第几个循环
ans是题目给出的复杂度
st数组 模拟栈 后进先出
/
string s;
char tar[N];
bool bz=false,vis[N];
/
bz表示是否出现语法错误
vis表示用过的变量名 用于判断是否出现语法错误
*/in int read()
{
int x=0;
char ch=getchar();
while (ch>'9' || ch<'0') ch=getchar();
while (ch>='0' && ch<='9')
x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return x;
}int main()
{
T=read();
while (T--)
{
memset(vis,false,sizeof(vis));
L=read(),cin>>s,ans=0;
bz=false,pos=0,cnt=0,num=0,tot=0;
if (s=="O(1)") ans=-1;
else
for (re int i=4; i<s.size()-1; ++i)
ans=ans*10+s[i]-'0';
for (re int i=1; i<=L; ++i)
{
char ch;
cin>>ch;
string a,b,c;
re int x=0,y=0;
if (ch=='F') //如果为'F' 即表示进入循环
{
if (num==0)
//如果 num=0 表示之前的所有清空 除了 变量名重复的语法错误外
memset(vis,false,sizeof(vis)),tot=max(cnt,tot),cnt=0,pos=0;
++num; // 循环次数+1
st[num]=0; //先标记为0 即为常数复杂度
cin>>a>>b>>c;
tar[num]=a[0]; //tar记录之前用过的变量 也是模拟栈实现
if (vis[a[0]-'a']) bz=true; //如果变量名重复 即为语法错误
vis[a[0]-'a']=true; //标记为用过的变量
if (b[0]=='n') x=100;
else for (re int j=0; j<b.size(); ++j)
x=x*10+b[j]-'0'; //对于b的提取
if (c[0]=='n') y=100;
else for (re int j=0; j<c.size(); ++j)
y=y*10+c[j]-'0'; //对于c的提取
if (x>y) ++pos,st[num]=-1; //表示不执行的循环 当前st标记为-1
if (pos) continue;
//如果前面存在不执行的循环仍未清空 即后面的循环的复杂度没有贡献
if (y==100 && x!=100) ++cnt,st[num]=1;
//为n的复杂度 且 起点不为 n 当前st的值标记为1
tot=max(tot,cnt);
//记录最大的复杂度 即程序的复杂度
}
else
{
vis[tar[num]-'a']=false; //循环结束 上次的变量名清空
if (st[num]==1) --cnt; //如果上次循环有贡献 则cnt需要-1
if (st[num]==-1) --pos; //如果上次是不执行的 则pos需要-1
--num; //当前执行少了 一个循环
}
}
if (num!=0 || bz==true) printf("ERR\n");
//如果末尾字符不够 或者变量重名 即为语法错误
else if ( (ans==-1 && tot==0) || (ans==tot) ) printf("Yes\n");
else printf("No\n");
//如果为常数复杂度 或者n^复杂度相同 即为yes 否则为no
}
return 0;
} -
07 年前@
代码短小精悍,易于理解
利用了快读的思想 -
07 年前@
记录: Accepted.
用栈模拟即可. -
-87 年前@
完全不想说什么。。。
此题水的一匹,考场上却调了近一个半小时
然后因为Yes和No的大小写搞错完美零分
给大家当一个教训吧。。。
- 1
信息
- ID
- 2029
- 难度
- 5
- 分类
- (无)
- 标签
- 递交数
- 792
- 已通过
- 178
- 通过率
- 22%
- 被复制
- 9
- 上传者