出 现 了
简 单 % 你
这道题把我的毒瘤码风都逼出来了
这不就是道模拟吗!
我们用一个栈存已经使用的变量,用一个栈存这一层是否对复杂度有贡献,同时写一个skip
函数,在出现循环不能进入的情况时强行跳过这一段代码
最后把复杂度算出来,对比就好了
变量解释:
code
:每一行的代码
F
:用于占位,内容一定为"F"
var
:变量名
from
:循环起始值
to
:循环终值
v
:每个变量是否被使用
vars
:被使用的变量名栈
top
:目前循环嵌套层数
n
:剩余输入层数
O
:小明算到的复杂度
now_comp
:当前复杂度
st ed
:循环始终值
n_const
:记录这一层是否对复杂度增长有贡献
函数解释:
read(int&, char*)
从字符串中读入数字,跳过特殊字符
inline void read(int &x, char *s) {
x = 0;
while(*s < 48 || 57 < *s) ++s;
for(; 48 <= *s && *s <= 57; ++s) x = x * 10 + (*s & 15);
}
skip(int&, int&)
跳过当前循环,并检测编译性错误
bool skip(int &n,int &top) {//把主函数里的n和top传进来,防止提前读到下一个点,还要维护已经使用的变量
//整个函数相当于一个微缩型的主函数
const int last = top - 1;
while(top != last && n--) {
gets(code);
if(*code == 'F') {//开启下一层循环
sscanf(code, "%s%s%s%s", F, var, from, to);//从代码中读取变量等信息
if(v[*var]) {
while(n--) gets(code);
puts("ERR");
return 1;
}
v[*var] = 1;//标记变量使用
vars.push(*var);//同上
top++;
}
else {
v[vars.top()] = 0;
vars.pop();
top--;
}
}
return 0;
}
reset
:每组数据的重置
void reset() {
memset(v, 0, sizeof(v));
while(vars.size()) vars.pop();
}
Main
:主函数
void Main() {
int n, O;
scanf("%d%s\n", &n, code + 1);
if(code[3] != 'n') O = 0;
else read(O, code + 1);//读复杂度
int now_comp = 0, ans = 0, top = 0;
int st, ed;
stack<int> n_const;
while(n--) {
gets(code);
if(*code == 'F') {
sscanf(code, "%s%s%s%s", F, var, from, to);
if(v[*var]) {//变量冲突
while(n--) gets(code);
puts("ERR");
return;
}
v[*var] = 1;
vars.push(*var);
top++;
if(*from == 'n')
if(*to == 'n')
n_const.push(0);
else {
if(skip(n,top)) return;
}
else
if(*to == 'n') {
now_comp++;
n_const.push(1);
}
else {
read(st, from);
read(ed, to);
if(st > ed) {
if(skip(n,top)) return;
}
else n_const.push(0);
}
}
else {
if(top == 0) {//E的个数比F还多
while(n--) gets(code);
puts("ERR");
return;
}
ans = max(ans, now_comp);
v[vars.top()] = 0;
vars.pop();
now_comp -= n_const.top();
n_const.pop();
top--;
}
}
if(top)//E的个数不够
puts("ERR");
else if(ans != O)
puts("No");
else puts("Yes");
}
总代码:
#include <cstdio>
#include <cstring>
#include <stack>
using namespace std;
inline int max(const int a, const int b) {
return a > b ? a : b;
}
inline void read(int &x, char *s) {
x = 0;
while(*s < 48 || 57 < *s) ++s;
for(; 48 <= *s && *s <= 57; ++s) x = x * 10 + (*s & 15);
}
char code[1100];
char F[2], var[2], from[10], to[10];
char v[1 << 7];
stack<char> vars;
bool skip(int &n,int &top) {
const int last = top - 1;
while(top != last && n--) {
gets(code);
if(*code == 'F') {
sscanf(code, "%s%s%s%s", F, var, from, to);
if(v[*var]) {
while(n--) gets(code);
puts("ERR");
return 1;
}
v[*var] = 1;
vars.push(*var);
top++;
}
else {
v[vars.top()] = 0;
vars.pop();
top--;
}
}
return 0;
}
void reset() {
memset(v, 0, sizeof(v));
while(vars.size()) vars.pop();
}
void Main() {
int n, O;
scanf("%d%s\n", &n, code + 1);
if(code[3] != 'n') O = 0;
else read(O, code + 1);
int now_comp = 0, ans = 0, top = 0;
int st, ed;
stack<int> n_const;
while(n--) {
gets(code);
if(*code == 'F') {
sscanf(code, "%s%s%s%s", F, var, from, to);
if(v[*var]) {
while(n--) gets(code);
puts("ERR");
return;
}
v[*var] = 1;
vars.push(*var);
top++;
if(*from == 'n')
if(*to == 'n')
n_const.push(0);
else {
if(skip(n,top)) return;
}
else
if(*to == 'n') {
now_comp++;
n_const.push(1);
}
else {
read(st, from);
read(ed, to);
if(st > ed) {
if(skip(n,top)) return;
}
else n_const.push(0);
}
}
else {
if(top == 0) {
while(n--) gets(code);
puts("ERR");
return;
}
ans = max(ans, now_comp);
v[vars.top()] = 0;
vars.pop();
now_comp -= n_const.top();
n_const.pop();
top--;
}
}
if(top)
puts("ERR");
else if(ans != O)
puts("No");
else puts("Yes");
}
int main() {
int T; scanf("%d", &T);
while(T--)
reset(), Main();
return 0;
}