본문 바로가기

알고리즘/백준알고리즘

[백준알고리즘-JAVA]15552번 풀이(빠른 A+B)

안녕하세요

인포돈 입니다.



백준 알고리즘 15552번 풀이입니다. 


* 참고사항
 - 개발환경은 eclipse을 기준으로 작성되었습니다.
 - java언어를 이용하여 문제를 풀이합니다.

 - 알고리즘 문제는 풀이를 보고 해답을 찾는 것도 중요하지만 무엇보다 스스로 풀이를 시도해봐야 합니다!!

(해당 풀이를 보기 전 충분히 문제에 대해 고민해봐야 합니다!)

 - 해당 풀이 말고도 수많은 풀이 방법이 존재합니다.


백준 15552(빠른 A + B)

 

문제

본격적으로 for문 문제를 풀기 전에 주의해야 할 점이 있다. 입출력 방식이 느리면 여러 줄을 입력받거나 출력할 때 시간 초과가 날 수 있다는 점이다.

 

Java를 사용하고 있다면, ScannerSystem.out.println 대신 BufferedReaderBufferedWriter를 사용할 수 있다. BufferedWriter.flush는 맨 마지막에 한 번만 하면 된다.

 

또한 입력과 출력 스트림은 별개이므로, 테스트 케이스를 전부 입력받아서 저장한 뒤 전부 출력할 필요는 없다. 테스트케이스를 하나 받은 뒤 하나 출력해도 된다.

 

입력

첫 줄에 테스트 케이스의 개수 T가 주어진다. T는 최대 1,000,000이다. 다음 TT 줄에는 각각 두 정수 AB가 주어진다. AB1 이상, 1,000 이하이다.

 

 

출력

각 테스트 케이스마다A+B를 한 줄에 하나씩 순서대로 출력한다.

 

입력 예시

5
1 1
12 34
5 500
40 60
1000 1000

출력 예시

2
46
505
100
2000

 

성공코드

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;

public class Main {

	public static void main(String[] args) {
	
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

			try {
				StringTokenizer st;
				int n =  Integer.parseInt(br.readLine());
				
				for(int i=0; i<n ; i++) {
					st = new StringTokenizer(br.readLine());
					bw.write(Integer.parseInt(st.nextToken()) + Integer.parseInt(st.nextToken()) + "\n");
				}
				
				br.close();
				bw.flush();
				bw.close();
				
			} catch (IOException e) {
				e.printStackTrace();
			}
			}
		}

 

해당 문제는 JAVA에서 흔하게 사용하는 println 또는 Scanner을 사용하여 문제를 풀게 될 시 오답이 나오게 됩니다. 문제에서 제시되었듯이 빠른 A+B이다. 그러면 println과 Scanner보다 빠르게 입력과 출력을 할 수 있는 방법이 무엇일까요??

 

바로 Bufferedreader와 Bufferedwriter입니다.

 

Bufferedreader - Scanner

Bufferedwriter - println

이런 식으로 매칭이 됩니다.

 

여기서 이해해야 하는 점이 있습니다.

 

1. 왜 Buffer을 이용한 읽고 쓰기가 빠른가?

2. 전체적인 문제 플로우

3. 문제 해결을 위한 메서드

 

이렇게 3가지를 이해하시면, 해당 문제를 쉽게 풀어가실 수 있습니다.

 

왜 Buffer을 이용한 읽고 쓰기가 빠른가?

 버퍼는 데이터를 한 곳에서 다른 한 곳으로 전송하는 동안 일시적으로 그 데이터를 보관하는 임시 메모리 영역입니다. 임시 메모리 영역에 우리가 입력한 문제를 담아뒀다가 한 번에 프로그램에 전송하는 역할을 담당하지요!

 

그러면 왜 임시 메모리를 거쳤다가 가는데 왜 더 빠른 가요???

 

예시로 설명해드릴 께요 상자 10개를 집에서 학교로 옮겨야 합니다.

 

Buffer를 사용하지 않으면 한 개를 들고 집에서 학교까지 가야 합니다.

Buffer를 사용하면 10개를 집 앞에 다 모아서 한 번에 학교로 가지고 갑니다.

 

이런 식으로 생각하시면 됩니다. 10번을 왔다 갔다 하는 것보다 가까운 곳에 다 모아뒀다가 한 번에 보내버리는 원리죠!

 

전체적인 문제 플로우

 

Bufferedread로 입력받기 -> 받은 입력을 for반복문을 통해 연속적으로 가공(StringTokenizer)하여 출력(Bufferedwriter)한다.

 

문제 해결에 필요한 메서드

 

Bufferedreader

 - readLine() : 한 줄의 문자를 읽어 문자열로 반환하는 메서드

 - close() : 버퍼를 종료한다.

 

Bufferedwriter

 - write() : () 안에있는 문자, 문자열, 숫자 등을 출력한다.

 - close() : 버퍼를 종료한다.

 - flush() : 버퍼에 남아있는 것들을 모두 출력한다.

 

StringTokenizer

 - nextToken() : StringTokenizer에 들어있는 다음 token을 문자열로 꺼낸다.

 

Integer

 - parseInt() : ()안에 있는 문자열을 intger형으로 바꿔준다.

 

 

추가적으로 더 빠르게 하는 방법들은 문제를 다 풀어보시고 상위 풀이를 살펴보시면 됩니다.

 

간략하게 몇 가지를 소개해드리면, StringTokenzier 대신에 StringBuilder를 사용하기.

StringTokenzier대신 문자를 가공할 수 있는 메서드를 재정의하기.

 

이렇게 상위분들이 풀이하셨더라고요.