Hayden's Archive

[알고리즘] 백준 2884번 : 알람 시계 / 백준 15552번 : 빠른 A+B 본문

Algorithm

[알고리즘] 백준 2884번 : 알람 시계 / 백준 15552번 : 빠른 A+B

_hayden 2020. 5. 31. 00:53

현재 프로그래머스 알고리즘 문제를 따로 풀고 있지만 백준 알고리즘 문제는 처음으로 풀어보았다. 프로그래머스는 기본적인 코드의 폼을 제공하지만 백준은 빈 화면만 제공한다. 그래서 처음에 계속 컴파일 에러 뜨길래 이유를 알 수 없어서 서치해봤더니 클래스 이름을 Main으로 해야 작동한다고 한다.(이건 정올도 마찬가지)

백준의 문제를 처음부터 단계별로 조금 풀었는데 기초적인 문제는 제외하고 기억에 남는 문제 위주로 포스팅하겠다.


알람 시계

알고리즘 문제 출처 : 백준 https://www.acmicpc.net/problem/2884

 

2884번: 알람 시계

문제 상근이는 매일 아침 알람을 듣고 일어난다. 알람을 듣고 바로 일어나면 다행이겠지만, 항상 조금만 더 자려는 마음 때문에 매일 학교를 지각하고 있다. 상근이는 모든 방법을 동원해보았지

www.acmicpc.net

 

내가 작성한 코드

경우의 수를 잘 따져주면 쉬운 문제. 45분 전으로 돌릴 때 음수가 나오면 60을 더해주고 시간을 1시간 전으로 돌려준다. 단 시간이 0시일 경우는 23시로 따로 저장해줘야 한다.

import java.util.Scanner;

public class Main {
	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);
		int h = sc.nextInt();
		int m = sc.nextInt();
		m -= 45;
		if(m < 0) {
			m += 60;
			if(h == 0) h = 23;
			else h -= 1;
		}
		System.out.println(h+" "+m);
	}
}

 


빠른 A+B

알고리즘 문제 출처 : 백준 https://www.acmicpc.net/problem/15552

 

15552번: 빠른 A+B

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

www.acmicpc.net

 

내가 작성한 코드

이 문제는 알고리즘보다 프로그래밍에 가까운 문제다. 자바에서는 흔히 값을 입력받거나 출력할 때 Scanner 객체와 System.out.println()을 사용하는데 가장 일반적인 방법 말고 더 빠른, 다른 방법을 사용하라는 문제였다. 그런 점에서 기억하기 위해 포스팅하는 코드. 사실 BufferedReader는 예전에 Stream 배울 때 함께 잠깐 배운 적이 있다. ( 관련 포스팅 : https://hayden-archive.tistory.com/107 )

처음 코드를 작성하는데 https://blog.naver.com/jamg123123/221723278633 를 참고하였다. nextToken()의 필요성은 https://blog.naver.com/accountee/221586498241을 통해 이해할 수 있었다.

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) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		StringTokenizer st = new StringTokenizer(br.readLine());
		int t = Integer.parseInt(st.nextToken());
		for(int i=0; i<t; i++) {
			st = new StringTokenizer(br.readLine());
			int a = Integer.parseInt(st.nextToken());
			int b = Integer.parseInt(st.nextToken());
			bw.write(a+b+"\n");
			bw.flush();
		}
		bw.close();
	}
}

 

이클립스에서는 문제없이 잘 작동했지만 백준에서 시간 초과...

 

무엇이 문제였을까 생각해봤는데 위 코드에서 flush()를 반복문 실시 횟수마다 호출하고 있었다. flush()는 최종적으로 출력할 때 맨 마지막에 한번만 써도 된다. 반복문 실시 횟수마다 호출하는 건 시간만 축낼 뿐이다.

 

그래서 코드를 다시 수정했다. 고작 flush()의 위치만 바꿨을 뿐이다.

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) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		StringTokenizer st = new StringTokenizer(br.readLine());
		int t = Integer.parseInt(st.nextToken());
		for(int i=0; i<t; i++) {
			st = new StringTokenizer(br.readLine());
			int a = Integer.parseInt(st.nextToken());
			int b = Integer.parseInt(st.nextToken());
			bw.write(a+b+"\n");
			
		}
		bw.flush();
		bw.close();
	}
}

 

통과했다!

 

그리고 문제에 첨부되어 있던 참고하면 좋을, 여러 언어들이 빠른 입출력 방법들 https://www.acmicpc.net/board/view/22716