题目描述
blablabla
样例
blablabla
C++ 代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
int n , line , st , idx , w;// st表示F的个数 , idx表示变量栈tmp的大小 , w表示最大的次幂
char op;// op表示当前操作
char tmp[100];
int read(char c[]){
int sum = 0;
if(c[0] == 'n') return 110;
else{
for(int i = 0 ; c[i] ; i ++)
sum = sum*10 + (c[i] - '0');
}
return sum;
} // 因为输入可能有数字,可能有字母n,所以在此统一输入,转化为数字
bool judge(char x){
for(int i = 0 ; i < idx ; i ++)
if(tmp[i] == x) return false;
tmp[idx++] = x;
return true;
}
bool Pow_judge(char time[] , int w){
int ans = 0;
for(int i = 4 ; time[i] != ')' ; i ++)
ans = ans*10 + (time[i] - '0');
return ans == w;
}
int main(){
cin >> n;
while(n --){
int w = 0;
bool flag1 = true , flag2 = true;
int Pow = 0;// 计算本次循环的次幂
char time[10];
memset(time , 0 , sizeof time);
cin >> line >> time;
for(int i = 1 ; i <= line ; i ++){
char lop;
lop = op;// lop表示上一次的操作 , 本行记录上一次操作。因为当且仅当上一次操作为F且本次操作为F时,才会有次幂
cin >> op;
if(op == 'F'){
st ++;
char x;
char op1[2] , op2[2];
int a , b;
cin >> x;
if(!judge(x)){ // 判断是否重复定义
if(flag2) puts("ERR");
flag2 = false;// 保证只输出一次ERR
}
cin >> op1;
a = read(op1);
cin >> op2;
b = read(op2);
if(a <= b && b == 110 && a != 110 && flag1) Pow ++; // 只有当a<=b且b为n且a不为n时,才会有次幂
if(a > b) flag1 = false;// 判断是否无法进入循环。若无法进入循环,则后面的F都是无效的,pow不会再增加。但是为了判断ERR,需要继续读入
}
else{
flag1 = true; // 重置flag1
st --; // 每个F都会使st加一,每个E都会使st减一
idx --; // 变量出栈
w = max(w , Pow); // 记录最大的次幂
Pow = max(Pow - 1 , 0); // 次幂最小为0
}
}
if(flag2){
if(st != 0)
puts("ERR"); // 判断是否缺少E
else if(w == 0 && time[2] == '1') puts("Yes");
else if(Pow_judge(time , w)) puts("Yes");
else puts("No");
}
w = 0;
st = 0;
idx = 0;
op = 0;
}
return 0;
}
/*
F i 1 1
0123456
*/
/* 感悟
1. 有时候在中途就可判断ERR,但是为了保证输出的正确性,需要继续读入,直到读完
2. 注意输出的次数,结果只需一次输出,否则如53行的ERR,若不用flag2判断,会输出多次
3. 要考虑周全,所有可能性都要考虑到,比如a是n
4. 如何正确读入有时需要多加思考 , 比如这道题,在读入时,可能时数字,可能是字母n
*/