[SWEA] 26927. 다트 최다 점수 집계 (D2, Java)

Jun·2026년 7월 27일

알고리즘

목록 보기
1/11

1. 문제 요약

0~9 사이의 숫자가 공백 없이 이어진 문자열이 주어진다. 여기서 가장 많이 등장한 숫자와 그 등장 횟수를 구하면 된다. 단, 최빈값이 여러 개면 그중 더 큰 숫자를 답으로 한다.

판의 수 T ≤ 50, 한 판의 다트 수 5 ≤ N ≤ 100
각 점수는 0~9 한 자리
출력: #판번호 최빈숫자 등장횟수

2. 접근 과정

값의 범위가 0~9로 딱 10개다. 크기 10짜리 카운팅 배열을 만들어 카운팅을 하려고 했다.
동점 처리는 배열을 인덱스 9부터 0까지 거꾸로 순회한다. 큰 숫자를 먼저 만나니까, 최댓값과 일치하는 순간 바로 break하면 그게 자동으로 가장 큰 최빈값이 된다.

3. 코드

package swea.D2_26927;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Solution {

  public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    StringBuilder sb = new StringBuilder();

    int t = Integer.parseInt(br.readLine());


    for (int i = 1; i <= t; i++) {
      int n = Integer.parseInt(br.readLine());

      int[] count = new int[10];
      int maxNum = 0;
      int maxNumCount = 0;

      String s = br.readLine();

      for (int j = 0; j < n; j++) {
        char c = s.charAt(j);
        int num = c - '0';
        count[num]++;
        maxNumCount = Math.max(maxNumCount, count[num]);
      }

      for (int j = count.length - 1; j >= 0; j--) {
        if (maxNumCount == count[j]) {
          maxNum = j;
          break;
        }
      }
      sb.append('#').append(i).append(" ").append(maxNum).append(" ").append(count[maxNum])
          .append("\n");


    }
    System.out.print(sb);
  }
}

append를 체이닝한 이유는 +를 쓰면 임시 StringBuilder가 생긴다는 설명을 자주 보아서 찾아보았는데, 이건 Java 8까지의 얘기다. Java 9부터 javac는 문자열 +를 invokedynamic으로 컴파일하고 StringConcatFactory가 런타임에 최적화된 메서드 핸들을 만들어준다. 임시 StringBuilder는 생기지 않는다.

그래도 중간 String 객체가 만들어졌다가 다시 sb 버퍼로 복사되는 것은 두 방식 모두 동일하다. 체이닝은 이 중간 단계 없이 버퍼에 바로 쓴다.

100만 줄 기준이면

방식힙 할당량소요 시간
append 안에서 +89 MB71~80 ms
append 체이닝36 MB67~70 ms

할당량은 2.5배 차이가 나는데 시간은 사실상 같았다. 짧게 살다 사라지는 객체는 JIT과 GC가 워낙 저렴하게 처리하기 때문에 체감 시간으로는 잘 드러나지 않는다고 한다.
결론으로 append 체이닝 굳이 안 해도 될 듯 하다...!

profile
꾸준하게

0개의 댓글