[BaekJoon] 2845번 - 파티가 끝나고 난 뒤 (java)
1. 문제
👉 문제 바로가기
- 조건
| 시간 제한 | 메모리 제한 |
|---|---|
| 1초 | 128MB |
- 문제
파티가 끝나고 나면, 사람들은 누가 파티에 왔는지와 얼마나 많은 사람들이 왔는지를 궁금해한다. 보통 파티는 매우 크게 열리기 때문에, 정확하게 몇 명이 참가했는지 알 수가 없다.
지난주 토요일에 상근이는 자신의 3학년 진학을 기념하면서 매우 성대한 파티를 열었다. 그리고, 상근이는 1m2당 몇 명의 사람이 있었는지 알고있다.
상근이의 파티는 정말 엄청난 규모였기 때문에, 대부분의 신문에도 기사가 실렸다. 상근이는 서로 다른 5개의 신문을 보면서 그 기사에 적혀져있는 참가자의 수를 적었다.
상근이는 자신이 알고있는 참가자의 수가 정확하다고 생각한다. 각 신문 기사에 실려있는 참가자의 수가 몇 명 만큼 잘못되어있는지 구하는 프로그램을 작성하시오.
- 입력
첫째 줄에 1m²당 사람의 수 L (1 ≤ L ≤ 10)과 파티가 열렸던 곳의 넓이 P (1 ≤ P ≤ 1000)가 주어진다.
둘째 줄에는 각 기사에 실려있는 참가자의 수가 주어진다. 10⁶보다 작은 양의 정수 5개가 주어진다.
- 출력
출력은 첫째 줄에 다섯 개의 숫자를 출력해야 한다. 이 숫자는 상근이가 계산한 참가자의 수와 각 기사에 적혀있는 참가자의 수의 차이이다.
- 예제
| 입력 | 출력 |
|---|---|
| 1 10 10 10 10 10 10 |
0 0 0 0 0 |
| 5 20 99 101 1000 0 97 |
-1 1 900 -100 -3 |
2. 풀이
for 반복문을 사용해 각 기사에 실려있는 참가자의 수를 입력받고 문자열에 출력할 값을 저장한다.
조건식의 결과가 참인 동안 반복적으로 실행하고자 하는 명령문 작성;
}
2개의 입력방식을 사용해서 결과를 출력한다.
- Scanner 클래스
- BufferedReader 클래스
2-1. Scanner 클래스
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int L = sc.nextInt(); // 1m²당 사람의 수
int P = sc.nextInt(); // 파티 장소 넓이
int[] arr = new int[5];
String str = "";
for(int i=0;i<5;i++){
arr[i] = sc.nextInt() - L * P; // 참가자 수 차이
str += arr[i] + " ";
}
System.out.println(str);
}
}
위와같이 객체를 생성할 때, Scanner(System.in) 에서
System.in은 입력한 값을Byte 단위로 읽는 것을 뜻한다.
int형 데이터를 입력받기 위해
nextInt()메서드를 사용한다.
[여기서 잠깐!]
2-2. BufferedReader 클래스 사용
3가지 출력 방식으로 문제를 풀어보고 비교해보자.
① StringBuilder
② BufferedWriter
③ System.out.println()
문자열 분리 방법으로는 StringTokenizer 클래스를 사용한다.
readLine() 메서드를 사용해 읽어온 문자열을 공백단위로 분리한다.
① BufferedReader + StringBuilder
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.StringTokenizer;
public class Main{
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
StringTokenizer st = new StringTokenizer(br.readLine());
int L = Integer.parseInt(st.nextToken()); // 1m²당 사람의 수
int P = Integer.parseInt(st.nextToken()); // 파티 장소 넓이
st = new StringTokenizer(br.readLine());
br.close();
int[] arr = new int[5];
for(int i=0;i<5;i++){
arr[i] = Integer.parseInt(st.nextToken()) - L * P; // 참가자 수 차이
sb.append(arr[i]).append(" ");
}
System.out.println(sb);
}
}
Integer.parseInt()을 사용해 readLine()으로 읽어온 String형 데이터를int형으로 변환시켜준다.
StringBuilder 클래스는 문자열을 동적으로 조작하기 위한 클래스로,append()를 사용해 문자열을 추가하여 새로운 문자열을 생성한다.
append()를 위와 같이 나눠서 쓰면 타입 변환과 문자열 연결 연산이 추가적으로 발생하지 않고 StringBuilder에 직접 추가하기 때문에 보다 더 효율적이고 빠르다.
② BufferedReader + BufferedWriter
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.IOException;
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 L = Integer.parseInt(st.nextToken()); // 1m²당 사람의 수
int P = Integer.parseInt(st.nextToken()); // 파티 장소 넓이
st = new StringTokenizer(br.readLine());
br.close();
int[] arr = new int[5];
for(int i=0;i<5;i++){
arr[i] = Integer.parseInt(st.nextToken()) - L * P; // 참가자 수 차이
bw.write(arr[i] + " ");
}
bw.flush();
bw.close();
}
}
BufferedWriter 클래스의 write() 메소드는 데이터를 내부 버퍼에 저장하고,flush() 메소드를 사용해 버퍼를 비우고 데이터를 출력한다.
BufferedWriter 클래스의 write() 메소드는 단독으로 int 형 값만 넣을 경우 아스키 코드값으로 인식되기 때문에 다른 문자가 출력된다. 때문에반드시 문자열과 int 형을 함께 넣어줘야int 값을 제대로 출력할 수 있다.
[여기서 잠깐!]
BufferedWriter 클래스에 대해 더 알아보고 싶으면 여기를 클릭하면 된다.③ BufferedReader + System.out.println()
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.StringTokenizer;
public class Main{
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int L = Integer.parseInt(st.nextToken()); // 1m²당 사람의 수
int P = Integer.parseInt(st.nextToken()); // 파티 장소 넓이
st = new StringTokenizer(br.readLine());
int[] arr = new int[5];
String str = "";
for(int i=0;i<5;i++){
arr[i] = Integer.parseInt(st.nextToken()) - L * P; // 참가자 수 차이
str += arr[i] + " ";
}
System.out.println(str);
}
}
3. 성능 비교
위에서 부터 순서대로
BufferedReader + StringBuilder
BufferedReader + BufferedWriter
BufferedReader + System.out.println()
Scanner
위와같이 입력 메소드와 알고리즘 구현 방법에 따라 시간이 달라질 수 있다.
입력의 경우 확실히 Scanner 보다는 BufferedReader 가 빠른 것을 볼 수 있다.
출력의 경우 System.out.println() 가 제일 느리다.
BufferedWriter 보다는 StringBuilder 가 빠른 것을 볼 수 있다.
(그러나 데이터 양이 커지면 커질 수록 BufferedWriter 가 더 빠르다.)
BufferedWriter는 일반적으로 I/O 작업으로 인해 비교적 느릴 수 있다.
반면에 StringBuilder는 문자열 조작에 최적화된 클래스로, 문자열 연산은 일반적으로 메모리 상에서 수행되므로 상대적으로 빠를 수 있다.
관련 페이지
Leave a comment