图灵奖得主 Edsger Wybe Dijkstra 是一位荷兰计算机科学家,他的名字非常令人困惑,以至于亚洲人很难发音。在 20 世纪 60 年代,他曾发表过如下名言:
多年来,我一直观察到,程序员的水平与他们编写的程序中 go to 语句的密度成反比。最近我发现了为什么 go to 语句的使用会产生如此灾难性的后果,我深信应该在所有“高级”编程语言中废除 go to 语句。
你不想编写低质量的代码,对吧?然而,你的源代码中没有任何循环语句。你源代码中唯一的流程控制语句是 if-goto。为了降低密度,你必须尝试消除源代码中所有用类 C 语言编写的 if-goto 语句,并按照以下方式将其替换为 do-while 循环:
- 假设
if-goto语句的形式为 “if (boolean_expression) goto some_label;”。 - 在
some_label声明的位置之后插入一个 “do {”。 - 将 ‘
if’ 替换为 ‘} while’。 - 删除 ‘
goto some_label’。
例如,以下代码:
int main() {
int score;
get_score:
scanf("%d",&score);
if (score < 0 || score > 100) goto get_score;
if (score < 60) goto fail;
fail:
puts("you are failed!");
return 0;
}将被修改为:
int main() {
int score;
get_score: do {
scanf("%d",&score);
} while (score < 0 || score > 100) ;
} while (score < 60) ;
fail: do {
puts("you are failed!");
return 0;
}上述代码无法编译并不令人惊讶。现在你的新任务是:给定一系列语句,请确定是否可以将所有 if-goto 语句替换为 do-while 循环,且不改变代码的输出。为简单起见,你可以假设所有语句仅包含以下两种形式:
- 形式 1:“
line_x: puts("x");”,其中 $x$ 是该语句对应的行号,且 “puts("x");” 会打印行号 $x$。 - 形式 2:“
if (expr_x()) goto line_y;”,其中 $x$ 是该语句对应的行号,$line_y$ 是程序中的一个有效标签。“expr_x()” 在前 $x$ 次调用时返回true,之后返回false。
注意,如果修改导致程序无法编译,则应认为程序的输出与原始输出不同。
输入格式
输入的第一行包含一个整数 $T$ ($T \le 20$),表示测试用例的数量。
每个测试用例由一系列语句组成。每条语句占一行,从第 1 行开始。共有三种类型的行:形式 1 的语句、形式 2 的语句以及 “END”。“END” 表示测试用例的结束。它只能出现在测试用例的最后一行,且不应被视为程序的一部分。单个测试用例中最多有 10000 条语句(不包括 END)。
输出格式
如果将所有 if-goto 语句替换为 do-while 循环后程序的输出不变,则在一行中输出 “good”。否则输出 “bad”。注意:如果程序变得无法编译,你也应该输出 “bad”。
样例
输入 1
3
line_1: puts("1");
if (expr_2()) goto line_1;
END
line_1: puts("1");
line_2: puts("2");
line_3: puts("3");
if (expr_4()) goto line_2;
line_5: puts("5");
if (expr_6()) goto line_2;
END
line_1: puts("1");
if (expr_2()) goto line_5;
line_3: puts("3");
line_4: puts("4");
line_5: puts("5");
END输出 1
good good bad