djm03178   6년 전

Q. 출력 초과가 뜹니다. 왜 그럴까요?

A. 출력 초과는 정답에 비해서 너무 많은 출력을 할 때 발생합니다. 이 문제에서 특히 그런 일이 많은 건, "불가능한 경우"에 NO만 출력해야 하는데 수많은 +와 -들을 출력하는 코드가 많아서 그렇습니다.

우선 "불가능한 경우"가 무엇인지 잘 생각해 보고, 중간 과정이 가능하다고 해서 바로바로 +나 -를 출력하지 말고 모아만 뒀다가, 불가능하다고 판단되는 상황이 오면 오로지 NO만 출력하고 다른 건 출력하지 않고 종료하도록 해야 합니다. 오로지 NO만 출력하도록 했는데도 출력 초과가 뜬다면 불가능한 경우를 잘못 판단한 것입니다.


Q. 런타임 에러가 납니다. 이유가 무엇일까요?

A. 여러 가지 원인이 있을 수 있지만, 우선적으로 고려해 볼 건 다음이 있습니다.

1. N이 10만까지 가능하므로, 스택의 크기도 최소 10만이 되어야 하고, 답은 개행 문자를 제외하고 20만자까지 나올 수 있습니다. 배열 크기를 충분하게 잡았는지 확인해보세요.

2. 스택이 비어있는데 스택의 top에 접근하는 연산을 해서는 안 됩니다. 보통의 배열에 대해서 [-1]에 접근해서도 안 되고, C++의 STL에 있는 stack이나 vector 등을 쓰더라도 top() 이나 back() 을 함부로 해서는 안 됩니다. 반드시 스택이 비어있는 상태인지에 대한 여부를 먼저 확인한 후 접근해야 합니다.


Q. 계속 틀리는데, 혹시 반례를 알 수 있을까요?

A. 이미 질문 게시판 https://www.acmicpc.net/board/...에 질문이 4페이지나 올라와 있습니다. 틀리는 코드에 대한 반례는 거의 다 있으리라 생각합니다.


Q. 시간 초과가 납니다...

A. 혹시 자신의 코드가 수열의 각 원소에 대해 지금까지 쌓아온 스택 전체를 순회해야 한다면 시간 복잡도가 O(N^2)이 되어 시간 초과가 될 가능성이 높습니다. 이 문제는 기본적으로 O(N)에 풀기를 원하는 문제입니다.

특히 자바를 쓰시는 분들 중에 이런 경우가 자주 보이는데, ArrayList나 LinkedList 등의 contains() 연산은 리스트를 전체 순회해야 하기 때문에 같은 문제가 발생합니다. 다른 언어들에서도 평범한 배열에 값이 있는지 없는지를 판단해주는 함수가 있다면 거의 이러한 시간 복잡도가 나올 것이므로, 주의해서 사용해야 합니다.

그리고 C++의 경우 endl 대신에 '\n'을 사용하면 시간을 획기적으로 단축할 수 있습니다.

*** Java의 경우, Integer 객체끼리의 비교를 == 또는 != 으로 하는 경우가 종종 보이는데, 이는 두 객체의 주소값이 같은지를 보는 것으로 절대로 해서는 안 되는 연산입니다. Java에서 미리 만들어 둔 객체들 범위인 127을 넘어가는 순간 더 이상 원하는 대로 동작하지 않습니다. intValue() 를 꼭 써서 비교하시기 바랍니다.

djm03178   6년 전

참고로, 원인이 꼭 채점 결과에 따라 저렇게만 나오는 것은 아닙니다. 전체 글을 다 읽고 해당되는 부분이 하나라도 있는지 확인해보세요.

hansangwon7   4년 전

Java에서

BufferedWriter 쓰면 채점 33% 쯤 오류나네요

StringBuilder 쓰면 잘됩니다

참고하면 좋을거 같아요

djm03178   4년 전

그럴 리가 없고, BufferedReader를 잘못 쓰셨거나, 두 코드를 다르게 쓰셨기 때문일 가능성이 99.999%쯤 됩니다.

hansangwon7   4년 전

bw.write > sb.append

bw.flush > sysout(sb);

이거만 바꿨습니다.


bufferedwriter 를 쓸 경우 buffer가 꽉 차면 알아서 flush 하는데 기본값이 8192 고

만약 정답은 NO인데 8192개 이상의 입력이 들어가서 flush 된다면 출력 초과가 나올 수 있다고 생각합니다.

어떻게 생각하시나요

djm03178   4년 전

출력 초과는 정답에 비해 너무 많은 출력을 한 경우 발생합니다. buffer가 꽉 차서 출력했다고 초과가 아닙니다.

djm03178   4년 전

무슨 말씀을 하신 건지는 알겠습니다만, BufferedWriter를 쓴 것 자체를 문제 삼으면 안 됩니다. +나 -를 추가할 때마다 바로바로 bw.write를 한 것이 문제일 뿐입니다. 꼭 StringBuilder를 쓰지 않더라도, 출력할 것을 따로 배열에 모아놓았다가 답이 NO가 아닌 경우에 마지막에 BufferedWriter에 몰아서 write해도 됩니다.

hansangwon7   4년 전

그건 저도 알죠...

근데 원래 결과가 NO인 case가 있는데 이 case의 입력이 너무 많아서 NO가 출력되기 전에 버퍼가 다 차서 출력되게 되면 출력초과가 나올 수 있다는 말이였어요

hansangwon7   4년 전

그래도 되기는 하겠네요

근데 저같이 시행착오 하시는 분 계실까봐 댓글 남겨둔거에요

songmin9813   3년 전

와...딱 제 케이스였네요. 진짜 이 댓글 아니었으면 엄청 헤맸을 것 같습니다. 감사합니다 다들ㅠㅠ

hhs2003   2년 전

위에 글을 읽어보니까 no가 나와야 하는 부분에서 자동 flush 가 나가서 계속 틀렸다고 나온것 같습니다.

스트링빌더로 바꾸니까 해결이 되네요....

djm03178   2년 전

네, BufferedWriter는 일정량 이상의 데이터가 버퍼에 쌓이면 자동으로 flush를 합니다.

댓글을 작성하려면 로그인해야 합니다.