라벨이 붙은 출력문과 정해진 횟수만 참이 되는 조건을 가진 if-goto 문으로 이루어진 프로그램에서, 모든 if-goto를 do-while 루프로 바꾸었을 때 프로그램의 출력이 그대로이고 컴파일도 되는지 판정한다.
어려움8시뮬레이션구현그래프DFS아직 제출이 없습니다시간 제한2초메모리 제한256 MB튜링상을 받은 에츠허르 데이크스트라(Edsger Wybe Dijkstra)는 네덜란드의 컴퓨터 과학자다. 이름은 발음하기가 까다롭다. 1960년대에 그는 이렇게 말했다.
여러 해 동안 나는 프로그래머의 수준이 그가 만드는 프로그램에 들어 있는 go to 문의 밀도에 대한 감소 함수라는 관찰에 익숙했다. 더 나중에 나는 go to 문을 쓰면 왜 그토록 참담한 결과가 나오는지 알아냈고, go to 문을 모든 "고급" 프로그래밍 언어에서 없애야 한다고 확신하게 되었다.
품질이 낮은 코드를 만들고 싶지는 않다. 그런데 내 소스 코드에는 반복문이 하나도 없고, 흐름을 제어하는 문장은 if-goto뿐이다. 밀도를 낮추려면 C와 비슷한 언어로 쓴 소스 코드에서 if-goto 문을 모두 없애고 다음 방법으로 do-while 문으로 바꿔야 한다.
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 문으로 바꿔도 프로그램의 출력이 그대로인지 판정하라. 문제를 간단하게 하려고 모든 문장이 다음 두 형태 중 하나라고 가정해도 된다.
line_x: puts("x"); 여기서 x는 이 문장의 줄 번호이고, puts("x")는 줄 번호 x를 출력한다.if (expr_x()) goto line_y; 여기서 x는 이 문장의 줄 번호이고, line_y는 프로그램 안에 있는 유효한 라벨이다. expr_x()는 처음 x번 호출에서 참을 돌려주고, 그 뒤로는 거짓을 돌려준다.바꾼 코드가 컴파일되지 않으면 프로그램의 출력이 원래와 다른 것으로 본다.
첫 줄에 테스트 케이스의 개수 T가 주어진다. (T≤20)
각 테스트 케이스는 문장의 나열이다. 각 문장은 한 줄에 하나씩 주어지고 줄 번호는 1부터 시작한다. 각 줄은 형태 1의 문장, 형태 2의 문장, END 중 하나다. END는 테스트 케이스의 끝을 나타낸다. END는 테스트 케이스의 마지막 줄에만 올 수 있고, 프로그램의 일부로 보지 않는다. 한 테스트 케이스의 문장은 최대 10000개다 (END는 세지 않는다).
각 테스트 케이스마다, if-goto 문을 모두 do-while 문으로 바꿔도 프로그램의 출력이 바뀌지 않으면 한 줄에 good을 출력하고, 그렇지 않으면 bad를 출력한다. 바꾼 코드가 더 이상 컴파일되지 않으면 bad를 출력한다.