백준 2840번 — 행운의 바퀴 (Java)

이승욱·2026년 3월 19일

자바알고리즘

목록 보기
18/33

문제 설명

행운의 바퀴에는 알파벳 대문자가 적혀 있고, 바퀴는 시계 방향으로만 회전한다.
각 회전마다

몇 칸 이동했는지
최종적으로 가리킨 문자

가 주어진다.

이 정보를 바탕으로 바퀴의 상태를 복원하는 문제이다.


입력

첫째 줄

N K
  • N : 바퀴 칸 개수
  • K : 회전 횟수

다음 K줄

S 문자
  • S : 이동 횟수
  • 문자 : 해당 위치 문자

출력

  • 가능한 경우: 바퀴 상태 출력
  • 불가능한 경우:
!

문제 해결 아이디어

핵심은 다음이다.

현재 위치를 추적하면서
문자를 기록하고
충돌과 중복을 검사한다

내가 작성한 코드

import java.util.*;

class Main
{
    public static void main (String[] args) {

        Scanner sc = new Scanner(System.in);

        int N = sc.nextInt();
        int K = sc.nextInt();

        char[] tire = new char[N];
        Arrays.fill(tire,'?');

        int count = 0;

        for(int i = 0; i < K; i++) {

            int roll = sc.nextInt();
            String input = sc.next();

            count += roll;

            if(tire.length <= count)
                count %= tire.length;

            if(tire[count] == '?' || tire[count] == input.charAt(0)) {
                tire[count] = input.charAt(0);
            } else {
                tire[0] = '!';
                break;
            }

            int dupl = 0;

            for(char t : tire) {
                if(t == input.charAt(0)) {
                    dupl++;
                }
                if(dupl > 1) {
                    tire[0] = '!';
                    break;
                }
            }
        }

        if(tire[0] == '!')
            System.out.print("!");
        else {
            for(int i = count; i >=0; i--) {
                System.out.print(tire[i]);
            }
            for(int i = tire.length-1; i>count; i--) {
                System.out.print(tire[i]);
            }
        }
    }
}

강의 코드

import java.util.Scanner;

class Main
{
    public static void main (String[] args) {

        Scanner sc = new Scanner(System.in);

        int N = sc.nextInt();
        int K = sc.nextInt();

        char[] wheel = new char[N];
        for (int i = 0; i < N; i++) wheel[i] = '?';

        int idx = 0;

        for (int i = 0; i < K; i++) {

            int step = sc.nextInt();
            char ch = sc.next().charAt(0);

            // 뒤로 이동 (핵심)
            idx = (idx - step % N + N) % N;

            if (wheel[idx] == '?' || wheel[idx] == ch) {
                wheel[idx] = ch;
            } else {
                System.out.println("!");
                return;
            }

            for (int j = 0; j < N; j++) {
                if (j != idx && wheel[j] == ch) {
                    System.out.println("!");
                    return;
                }
            }
        }

        for (int i = 0; i < N; i++) {
            System.out.print(wheel[(idx + i) % N]);
        }
    }
}

내 코드 vs 강의 코드 비교

1. 위치 이동 방식

내 코드

count += roll;
count %= N;

앞으로 이동

(idx + step) % N

강의 코드

idx = (idx - step % N + N) % N;

뒤로 이동

(idx - step + N) % N

핵심 차이

같은 문제지만 기준이 다르다.

방식해석
내 코드포인터가 앞으로 이동
강의 코드바퀴가 돌아가므로 포인터는 반대로 이동

같은 원형 구조
하지만 좌표 기준이 다름

2. 방향 해석 차이

내 코드

현재 위치를 기준으로
시계 방향으로 이동

강의 코드

바퀴가 시계 방향으로 돌았으므로
포인터 기준은 반대로 이동

3. 출력 방식

내 코드

뒤에서부터 출력 + 나머지 출력

→ 직접 분리해서 출력


강의 코드

wheel[(idx + i) % N]

원형 배열 그대로 출력


4. 구현 안정성

항목내 코드강의 코드
위치 계산직관적수학적
출력분리 처리모듈 연산
확장성낮음높음

핵심 개념

1. 원형 배열

(idx + step) % N
(idx - step + N) % N

2. 좌표 기준 선택

이 문제의 핵심은

내가 움직이는가?
바퀴가 움직이는가?

이 차이이다.


3. 충돌 검사

같은 위치 다른 문자 → 실패
같은 문자 2개 존재 → 실패

시간 복잡도

O(K × N)

최대

100 × 25 = 2500

→ 충분히 빠름


정리

이 문제는 단순 구현 문제처럼 보이지만,
실제로는 원형 배열을 어떻게 해석하느냐가 핵심이었다.

내 코드는

앞으로 이동하는 방식

강의 코드는

뒤로 이동하는 방식

을 사용했다.

두 방식 모두 정답이지만,
강의 코드처럼

(idx - step + N) % N

을 사용하는 방식이
원형 배열 문제에서 더 일반적이고 안정적인 접근이다.

profile
아는거 없는 전공자

0개의 댓글