落谷P3952:https://www.luogu.org/problemnew/show/P3952
思路:
有关语法错误:
- F与E不匹配(F多或E多)——栈1(标记)
- 新建变量未销毁重复声明——栈2(存变量名)
计算复杂度:每次遇到E通过栈1计算
关于栈1标记:
1——有效循环:复杂度乘n
2——常数循环:复杂度不变
3——无效循环:往后的循环均不算
栈1从前向后遍历
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int getm(char s[]){
int len=strlen(s);
if(len==4){
return 0;
}
else{
int num=0;
int i=0;
while(s[i]<'0' || s[i]>'9'){
i++;
}
while(s[i]>='0' && s[i]<='9'){
num*=10;
num+=s[i]-'0';
i++;
}
return num;
}
}
int calculate(int stack[],int top){
int t=0;
for(int i=0;i<=top;i++){
if(stack[i]==1){
t++;
}
else if(stack[i]==2){
continue;
}
else if(stack[i]==3){
break;
}
}
return t;
}
bool check(char stackname[],int top){
for(int i=0;i<top;i++){
for(int j=i+1;j<=top;j++){
if(stackname[i]==stackname[j]){
return true;
}
}
}
return false;
}
int main(){
int t;
cin>>t;
int line;
char s[15];
while(t--){
scanf("%d%s",&line,s);
int m=getm(s);//得到复杂度
char str[15];
int top=-1,stack[201]={};
char stackname[201]={};//stack用于标记,stackname用于存变量
int e=0;//实际复杂度
bool err=false;//语法错误
for(int i=0;i<line;i++){
scanf("%s",str);
if(err==true){//出错则无需考虑
if(str[0]=='F'){
scanf("%s",str);scanf("%s",str);scanf("%s",str);
}
else if(str[0]=='E'){
continue;
}
}
if(str[0]=='F'){//循环体
char v=0;//变量名
int x=0,y=0;//循环起点和终点
bool flag_x=false,flag_y=false;//是不是n
scanf("%s",str);v=str[0];
scanf("%s",str);
if(str[0]=='n'){
flag_x=true;
x='n';
}
else{
int len=strlen(str);
for(int i=0;i<len;i++){
x*=10;x+=str[i]-'0';
}
}
scanf("%s",str);
if(str[0]=='n'){
flag_y=true;
y='n';
}
else{
int len=strlen(str);
for(int i=0;i<len;i++){
y*=10;y+=str[i]-'0';
}
}
++top;
if(!flag_x && flag_y){//常数:n
stack[top]=1;
}
else if(!flag_x && !flag_y && x<=y){//常数:常数 && a<=b
stack[top]=2;
}
else if(flag_x && flag_y){//n:n
stack[top]=2;
}
else{//无效循环
stack[top]=3;
}
stackname[top]=v;
}
else if(str[0]=='E'){//结束循环
if(top<0){//已经栈空
err=true;
continue;
}
e=max(e,calculate(stack,top)); // 计算当前复杂度
if(check(stackname,top)==true){//检查变量名是否重复
err=true;
}
top--;
}
}
if(top!=-1){//如果栈不空
err=true;
}
if(err==true){
cout<<"ERR"<<endl;
}
else{
if(e==m){
cout<<"Yes"<<endl;
}
else{
cout<<"No"<<endl;
}
}
}
}
注意代码的健壮性,比如getm()函数如何考虑,还有不要用gets()