https://www.acmicpc.net/problem/2738

import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int[][] ary1 = new int[n][m];
int[][] ary2 = new int[n][m];
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
ary1[i][j] = sc.nextInt();
}
}
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
ary2[i][j] = sc.nextInt();
}
}
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
System.out.print(ary1[i][j] + ary2[i][j] + " ");
}
System.out.println();
}
}
}
처음 작성한 코드. 일단 문제부터 풀고 성능 향상을 해보자 하고 익숙한 Scanner도 사용하고 StringBuilder 대신 println을 여러번 반복 실행하는 코드로 작성했다. 문제는 맞았고, 아래는 아는 정보들 안에서 리팩토링한 버전
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
String str = br.readLine();
st = new StringTokenizer(str);
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
int[][] ary1 = new int[n][m];
for(int t = 0; t < 2; t++){
for(int i = 0; i < n; i++){
st = new StringTokenizer(br.readLine());
for(int j = 0; j < m; j++){
ary1[i][j] = ary1[i][j] + Integer.parseInt(st.nextToken());
}
}
}
StringBuilder sb = new StringBuilder();
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
sb.append(ary1[i][j]).append(" ");
}
sb.append("\n");
}
System.out.println(sb);
}
}
우선 Scanner 대신 BufferedReader 사용해서 속도를 올렸다.
Scanner와 BufferedReader / BufferedWriter의 차이점과 사용법
이때까지 귀찮아서 Scanner만 항상 사용했는데, 이제야 정리를 해보고, 오늘 부로 절대 Scanner를 사용하는 과거로 돌아가지 않을 것이다. 1. Scanner Scanner는 띄어쓰기와 개행문자를 경계로 값을 인식
juno-juno.tistory.com
BufferedReader는 문자열을 읽어오는 방식이라 StringTokenizer를 사용해서 공백 기준으로 분리한 뒤 Integer.parseInt() 사용해서 정수로 변환해서 받는다.
배열은 굳이 2개를 생성하지 않고, 하나만 생성해서 합을 누적해서 저장했다.
값을 따로 입력 안 하면 배열 안의 값들은 다 0으로 초기화 되므로 입력받은 수들을 바로 덮어써도 무방함
배열 2개만 더하는 것은 문제에서 제시됐으니 처음 for문은 2번만 반복
n행에 입력할 수가 같은 줄로 공백 기준으로 입력되므로 st = new StringTokeinzer(br.readLine())을 두번째 for문 안(3번째 for문 밖)에 위치시킨다.
이후 값을 일일히 입력할 3번째 for문에서 배열(int[n][m])에 공백 기준으로 나눠진 값(st.nextToken())을 하나씩 입력한다.
그럼 한 줄에 입력된 3개의 값이 n행에 0부터 m-1열까지 순서대로 입력됨
그리고 결과 배열을 StringBuilder 사용해서 반복문 안쪽에선 값들만 sb에 .append() 사용해서 값 하나씩 공백 추가해서 넣고,
(행 하나 다 넣었을 때마다 append("\n")로 줄바꿈 해야함)
출력문은 한 번만 사용해서 출력했다.
그렇다면 나름 수정한 2번째 코드를 지교수님은 어떻게 보셨을까
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
int[][] sum = new int[n][m];
for (int t = 0; t < 2; t++) {
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < m; j++) {
sum[i][j] += Integer.parseInt(st.nextToken());
}
}
}
StringBuilder sb = new StringBuilder(n * m * 4); // 대충 넉넉히
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (j > 0) sb.append(' ');
sb.append(sum[i][j]);
}
sb.append('\n');
}
System.out.print(sb);
}
}
1. 불필요한 String 변수 없애고 한 줄로 st = new StringTokenizer(br.readLine()); 으로 사용
2. 덧셈 표현 간결하게 += 사용
3. 출력의 행 끝 공백(append(' ')) 제거
4. StringBuilder의 초기 용량 잡아두기
그리고 내가 한 방식 외에 그냥 성능, 가독성 좋고 코테에서 점수 잘 받을만한 코드 작성해달라 해봤다.
import java.io.*;
public class Main {
// 매우 빠른 입력기 (Java 8)
private static final class FastScanner {
private final InputStream in;
private final byte[] buffer = new byte[1 << 16];
private int ptr = 0, len = 0;
FastScanner(InputStream in) {
this.in = in;
}
private int readByte() throws IOException {
if (ptr >= len) {
len = in.read(buffer);
ptr = 0;
if (len <= 0) return -1;
}
return buffer[ptr++];
}
int nextInt() throws IOException {
int c;
do {
c = readByte();
} while (c <= ' ' && c != -1);
int sign = 1;
if (c == '-') {
sign = -1;
c = readByte();
}
int val = 0;
while (c > ' ') {
val = val * 10 + (c - '0');
c = readByte();
}
return val * sign;
}
}
public static void main(String[] args) throws Exception {
FastScanner fs = new FastScanner(System.in);
int n = fs.nextInt();
int m = fs.nextInt();
int[][] sum = new int[n][m];
// A + B를 바로 누적
for (int t = 0; t < 2; t++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
sum[i][j] += fs.nextInt();
}
}
}
StringBuilder sb = new StringBuilder(n * m * 4);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (j > 0) sb.append(' ');
sb.append(sum[i][j]);
}
sb.append('\n');
}
System.out.print(sb);
}
}
FastScanner는 초면인데
..
다음에 알아보도록 하자.

'Java' 카테고리의 다른 글
| [프로그래머스][Lv.2] 최댓값과 최솟값 (0) | 2026.03.05 |
|---|---|
| [백준] 코딩테스트 문제 2566: 최댓값 (0) | 2026.03.04 |
| [백준] 코딩테스트 문제 25206: 너의 평점은 (0) | 2026.03.03 |
| [백준] 코딩테스트 문제 1316: 그룹 단어 체커 (0) | 2026.03.02 |
| [백준] 코딩테스트 문제 1157: 단어 공부 (0) | 2026.02.25 |