seolminsik   1년 전

같은 pseudo code로 작성한 Go풀이와 C++풀이에서 C++풀이만 맞았습니다.

그래서 Go로 풀이할 때 파일 입출력 시간 때문에 시간 초과가 났다고 생각이 됩니다만, Fscan을 사용하고 있는 현재 상황에서 파일 입출력을 잘못 이용하고 있는 지 또는 알고 보면 다른 부분에서 문제가 있었는지 조언을 듣고 싶습니다!

C++ 풀이 : https://www.acmicpc.net/source...

Go 풀이 : https://www.acmicpc.net/source...

bamgoesn   1년 전

출력이 느립니다.

fmt.Fprintln(os.Stdout, ...)을 하게 되면 출력 후 그때그때 flush를 하게 됩니다. 이러면 Fprintln을 사용하는 의미가 없습니다.

빠른 출력을 위해서는 출력할 문자를 담아뒀다가 한꺼번에 출력하는 BufferedWriter를 사용해야 합니다. 아래와 같이 사용할 수 있습니다.

단, 반드시 수동으로 BufferedWriter를 flush해줘야 합니다. 이는 main 함수 맨 앞에 defer out.Flush()를 추가함으로써 수행할 수 있습니다.

bamgoesn   1년 전

...는 그렇게 해도 TLE가 남을 확인했습니다. 시간이 나면 다른 문제가 있는지 확인해보겠습니다...

bamgoesn   1년 전

확인해보니 입력도 느리네요.

현제 입력을 BufferedReader와 Fscan으로 받고 계시는데, 이게 꽤 빠르긴 하지만 이 문제가 워낙에 입력이 많다보니 이거로는 부족한 것 같습니다. 개인적인 추측으로는 Fscan 함수의 특성상 문자열을 포매팅해서 변수에 저장하는 과정에 체크가 좀 더 많이 들어가는 것 같은데, 뇌피셜이라서 확실하진 않습니다.

빠른 입력을 받는 방법 중엔 BufferedScanner를 활용하는 방법이 있습니다. BufferedScanner는 입력을 띄어쓰기나 줄바꿈 등의 단위로 쪼개서 문자열로 입력을 받게 해줍니다. var sc = bufio.NewScanner(os.Stdin)과 같이 선언할 수 있으며, sc.Scan(); str := sc.Text()를 통해 sc가 스캔한 문자열(토큰)을 받아올 수 있습니다. 이를 직접 strconv.Atoi나 strconv.ParseInt 등으로 변환하면 보다 빠른 입력이 가능합니다.

아래 예시와 같이 사용할 수 있습니다. main 함수에서 sc.Split(bufio.ScanWords)를 통해 sc가 입력을 whitespaces 단위로 잘라서 읽게 할 수 있습니다. bufio.ScanWords 대신 bufio.ScanLines를 쓰면 줄 단위로 자를 수도 있습니다. 기본값은 줄 단위로 읽는 것입니다. 다만 sc.Split을 한 번 실행한 후 스캔을 진행하다가 중간에 토큰 방식을 바꾸기 위해 sc.Split을 호출하면 패닉합니다.

herdson   1년 전

go를 공부해본 적은 없지만 여기를 보면 도움이 될 것 같습니다.

seolminsik   1년 전

윗 두분 모두 너무 감사드립니다 특히 bamgoesn님 자세한 설명 너무 고맙습니다!!

Go언어가입출력 방법이 특히 헷갈려서 정신이 없었는데 큰 도움이 된 것 같습니다.

다시 한 번 감사드립니다.

bamgoesn   1년 전

덤으로... bufio.Scanner를 사용했을 때 EOF를 판정하는 건 아래와 같이 하시면 됩니다.

Scanner의 Scan 메서드는 bool형 변수를 반환하는데, 스캔할 토큰이 있으면 true를, 토큰이 남아있지 않으면 false를 반환합니다. 그러니까 대략 아래와 같이 코드를 쓰시면 EOF에 도달했는지 안 했는지 판단을 할 수 있을 겁니다.

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