백준 입문자들을 위한 좋은 설명 문제 감사합니다!
이 문제를 먼저 풀었다면 한창 검색하고 돌아다닐 시간을 아낄 수 있었겠네요
15552번 - 빠른 A+B
감사합니다. 혹시 블로그 링크는 어디 있나요?
문제 설명에 주어져 있습니다.
Node.js의 경우 매 번 console.log로 출력하면 시간초과를 받고, 하나의 문자열에 결과값과 개행문자를 저장해서 마지막에 출력했을 때 1496ms 받아서 통과했습니다.
C#
C# 코드입니다.
제가 한 코드이지만 이해가 전혀 안 갑니다...
단지 출력 부분에서 stringbuilder로 출력했을 뿐인데 정답처리가 되더군요
그냥 for문에서 연산 후 바로 writeline() 했을 때는 시간 초과가 나더니...
OCaml 코드입니다. 29xx ms로 겨우 통과했었는데, 최근에 재채점 데이터 추가되면서 시간초과가 뜨네요 ㅠ
C# 부연 설명
Console.Read 는 별 문제 없습니다.
Console.Write 함수들은 기본적으로 매 출력마다 flush 연산을 실행합니다.
"인터렉티브" 딱지가 붙지 않은 문제에서는 출력할 때 마다 무거운 flush 연산을 수행 할 필요가 없습니다.
다음 두 가지 방법 중 하나를 사용해야 합니다.
1) StringBuilder 에 출력할 내용을 모아둔 뒤 한꺼번에 출력하기. (위에 있는 두 분의 코드는 이 방법을 선택했습니다)
2) auto flush 를 하지 않는 output stream 을 Console 에 연결하기. 이 방법을 쓸 경우 프로그램 종료하기 전에 반드시 Console.Out.Flush() 를 수행해야 합니다. (아래 소스 참고)
C# 도 보너스 시간이 있는지 기존의 Console.ReadLine(), Console.Write() 를 사용해서 출력만 StringBuilder 로 모았다가 한번에 출력해줘도 1.3초 컷으로 통과됩니다.
똑같은 로직을 Console.In 으로 입력을 받고 Console.Out 으로 출력했을 때 1.18초가 걸렸습니다. 단, 반복문 내에서 using 을 돌리는 게 아닌 using 내부에서 반복문을 돌립니다.
똑같은 로직을 Console.OpenStandardInput() 과 Console.OpenStandardOutput() 으로 출력했을 때 0.9초가 걸렸습니다.
Console.In 과 Out 의 경우 TextReader, TextWriter 였고 OpenStandard 의 경우 StreamReader, StreamWriter 였습니다.
실력이 미천해서 왜 차이가 나는지는 모르겠는데 아무튼 Stream 객체가 더 빨랐습니다. 참고용 링크 몇개 첨부하겠습니다...
https://docs.microsoft.com/ko-...
어쩌다 발견하게 된 사실인데, Ruby의 puts는 빠르지 않습니다. gets는 빠른 게 맞다고 쳐도, puts의 자동 flush는 최악의 경우 실행 시간을 6배 이상 느리게 만들 수 있습니다.
실험 결과와 해결 방법을 기록한 포스트 링크를 함께 올립니다. https://www.acmicpc.net/board/...
Scheme 코드입니다. io모듈을 사용해 보니 C를 이용하지 않고 2664ms으로 시간 제한을 통과할 수 있었습니다.
Scheme 코드입니다. C를 이용해 단일 정수를 받는 방식으로 작성해봤습니다.
이렇게 하면 chicken io를 사용할 때처럼 string-split 등을 사용하지 않아도 됩니다.
코드에서 (void)와 + 1은 반환 값 무시 컴파일러 경고를 없애기 위해 사용했으니 신경쓰지 않으셔도 됩니다.
제출 시 약 700 ms 전후의 결과를 볼 수 있었습니다.
감사합니다.
[소스] https://www.acmicpc.net/source...
덧, 함수형을 적극 권장하는 스킴이라 그런지 루프 대신 재귀로 구현했더니 오히려 시간이 줄어든 모습을 보였습니다.
이 점 참고하시면 좋을 것 같습니다.
댓글을 작성하려면 로그인해야 합니다.
jh05013 6년 전 157
다른 언어에 대해 알고 계시는 것이 있으면 답글로 달아 주세요.
C
scanf/printf는 충분히 빠릅니다.
C++
Java
BufferedWriter 외에도, StringBuilder로 출력을 모아 놓았다가 그 String을 System.out.println하는 방법도 있습니다.
Python
rstrip을 하라는 건 문자열 자체를 변수에 저장하고 싶을 때 얘기지, 개행문자가 맨 끝에 들어와도 int 변환이나 split()을 그대로 할 수 있습니다. 즉 int(sys.stdin.readline()), sys.stdin.readline().split() 이렇게 해도 아무 문제 없습니다. 참고로 이름이 꽤 길기 때문에 저는 input = sys.stdin.readline을 맨 처음에 함으로써 쓰는 편입니다.
Kotlin
Java처럼 BufferedReader와 BufferedWriter를 쓰면 됩니다.
Ruby
gets와 puts는 충분히 빠릅니다.
Go
bufio를 import하면 버퍼를 사용한 빠른 입출력이 가능합니다.
C#
StreamReader로 읽고, StringBuilder로 출력을 모아 놓았다가 그 String을 Console.WriteLine하는 방법이 있습니다. BufferedStream과 StringWriter로 조금 더 향상시킬 수 있는 것 같으나 자세한 것은 다른 분의 답변을 기다리겠습니다.
VB
StringBuilder로 출력을 모아 놓았다가 그 String을 Console.WriteLine하는 방법이 있습니다.
Rust
아래 "rust05013"으로 올린 댓글을 참조해 주시기 바랍니다.
Swift
fread로 여러 바이트를 한번에 읽고, 정수를 읽어야 할 때마다 미리 읽어둔 문자열로부터 정수를 파싱하면 됩니다. 꽤 복잡한 방법이지만, 이것보다 간단한 방법은 아직 찾지 못했습니다.
Text
입출력 파일이 예제 포함 2개 이상이기 때문에 Text로는 이 문제를 풀 수 없습니다.
아희
안타깝게도 아희로는 이 문제를 풀 수 없습니다. 입출력하는 방법이 하나뿐인데 시간초과가 납니다.