시뮬레이션(Simulation) 문제 — 상태를 직접 움직이는 사고법

Seongyong's PLOG·2025년 10월 19일

알고리즘

목록 보기
3/4
post-thumbnail

1. 시뮬레이션 문제란

시뮬레이션 문제는 주어진 규칙에 따라 상태를 직접 변화시키며 최종 결과를 도출하는 문제 유형이다.
정해진 공식이나 점화식으로 답을 구하는 DP, 탐색, 수학적 문제와 달리
“규칙을 그대로 구현해야 하는 문제”가 대부분이다.

즉, 해답의 핵심은 알고리즘보다는 과정의 재현이다.
문제에서 말하는 조건, 반복, 제약을 하나하나 실제 코드 흐름으로 옮겨야 한다.
이 때문에 코드의 복잡도는 높지만, 알고리즘 자체는 단순한 경우가 많다.


2. 시뮬레이션 문제의 특징

  1. 명확한 규칙 기반 동작

    • 문제에 “~을 반복한다”, “조건에 따라 ~을 수행한다” 등의 문장이 많다.
    • 수학적 최적화보다는 순서 제어가 중심이 된다.
  2. 상태 변화 추적이 핵심

    • 배열, 리스트, 큐 등에서 “현재 상태”를 기준으로 다음 상태를 계산.
    • 변화가 누적되기 때문에, 매 단계에서 상태 관리가 중요하다.
  3. 조건 분기와 반복문 중심의 구조

    • if / while / for문이 주요 논리 흐름을 구성.
    • 탐색보다는 “규칙을 따라가며 결과를 갱신”하는 방식.

3. 시뮬레이션 문제를 푸는 사고 순서

시뮬레이션 문제를 풀 때는 다음과 같은 사고 과정을 거친다.

  1. 문제 속 객체(Object) 정의

    • 어떤 것이 ‘상태’를 가지는지 파악한다.
    • 예: 스위치의 on/off, 원판의 회전 각도, 벽의 높이 등
  2. 상태를 표현할 자료 구조 설계

    • 1차원 배열, 2차원 배열, offset 배열 등
    • 단순히 저장이 아니라 “시간에 따라 변할 수 있는 구조”로 설계해야 한다.
  3. 명령 또는 이벤트 정의

    • 문제에서 주어진 동작을 ‘하나의 함수 단위’로 생각한다.
    • ex) rotate(), flip(), spread(), erase()
  4. 반복 구조 설계

    • 명령이 여러 번 주어지는 경우, 입력 순서대로 처리.
    • 각 단계에서 상태를 정확히 갱신.
  5. 종료 조건과 출력 관리

    • 특정 횟수 반복 또는 조건 충족 시 종료.
    • 누적된 상태로부터 결과 계산.

이 과정은 실제 프로그램을 설계하는 것과 매우 유사하다.
그래서 시뮬레이션 문제는 “코드 구현 능력”을 가장 직접적으로 평가하는 문제 유형이라 할 수 있다.


4. 시뮬레이션 문제의 통상적 풀이 방법

단계내용예시
1초기 상태 구성입력을 배열이나 객체로 저장
2명령 실행조건에 따라 상태 갱신
3경계 조건 처리배열 인덱스 범위, 대칭 여부 등
4누적 연산 또는 조건 비교삭제, 누적, 평균 조정 등
5결과 계산전체 합, 특정 상태 수 등

여기서 중요한 점은 “모든 상태 변화는 즉시 반영하거나, 별도 구조로 저장 후 일괄 반영해야 한다”는 것이다.
즉, 문제의 규칙을 따라가는 과정에서 타이밍과 순서가 핵심 포인트가 된다.


5. 예제별 풀이 분석

아래의 세 문제는 모두 시뮬레이션의 전형적인 형태를 가지고 있다.
각각의 코드는 “상태를 직접 제어하고 갱신하는 구조”라는 공통된 흐름을 갖고 있다.


(1) 스위치 켜고 끄기 — 단순 규칙 기반 시뮬레이션

이 문제는 가장 기초적인 형태의 시뮬레이션이다.
스위치의 on/off 상태를 그대로 구현하는 문제로, 상태 갱신의 반복이 핵심이다.

상태 정의

  • switches[]: 각 스위치의 현재 상태(boolean)
  • true = 켜짐, false = 꺼짐

규칙 시뮬레이션

  • 남학생: 받은 번호의 배수마다 상태 반전
  • 여학생: 좌우 대칭이 유지되는 범위까지만 확장 반전

구현 포인트

  • 실제 시뮬레이션은 단순한 반복문으로 구성
  • 각 명령이 입력될 때마다 배열 상태가 즉시 갱신됨

핵심 요약

  • 명령 → 즉시 반영 구조
  • 시뮬레이션의 가장 단순한 형태 (조건 + 반복)

(2) 빗물 — 구조적 시각화를 통한 상태 추적

이 문제는 시뮬레이션을 “시각적으로 표현”하는 형태다.
실제 물이 고이는 상황을 배열로 그대로 표현했다.

상태 정의

  • world[H][W]: 벽의 유무 (1이면 벽, 0이면 빈 공간)

로직 흐름

  1. 입력된 벽 높이를 기준으로 world[][] 구성
  2. 각 행을 기준으로 좌→우로 스캔
  3. 첫 벽 이후 두 번째 벽 사이에 생긴 빈 칸 개수를 물로 카운트

구현 의도

  • 1차원으로도 가능하지만, 실제 고이는 모습을 2차원으로 시뮬레이션
  • 물이 쌓이는 구조를 코드로 “그려본다”는 느낌에 가깝다.

핵심 요약

  • 상태를 직접 구조화한 형태의 시뮬레이션
  • 시각화 중심 접근 (직관적, 절차적)

(3) 원판 돌리기 — 복잡한 상태 전이와 다단계 규칙

이 문제는 전형적인 고난도 시뮬레이션 문제다.
단일 조건의 반복이 아니라,
여러 개의 규칙이 순차적으로 연쇄적으로 작동하는 구조를 가진다.

상태 정의

  • circle[][]: 각 원판의 숫자 상태
  • pos[]: 각 원판의 회전 offset 상태

주요 시뮬레이션 단계

  1. 회전 처리 — pos[]를 이용해 offset 이동
  2. 인접한 수 탐색 및 삭제 표시
  3. 삭제 후 평균 조정
  4. 다음 명령 반복

구현 의도

  • 실제 회전을 수행하지 않고 offset으로 상태 추적
  • 삭제와 평균 조정을 별도 단계로 분리하여 로직 충돌 방지

핵심 요약

  • 다단계 시뮬레이션의 대표 예시
  • 한 번의 명령에 여러 상태 변화 발생
  • offset을 이용해 메모리 효율성과 명확한 제어 구조 확보

6. 시뮬레이션 문제에서 중요한 사고

  1. 문제를 코드로 옮기는 순서를 정확히 설계해야 한다.

    • 조건을 해석하는 순서가 곧 정답을 결정한다.
  2. 상태를 한눈에 볼 수 있는 구조를 만들어야 한다.

    • 배열, 리스트, offset 등은 단순 저장이 아니라 ‘현재 시점의 상태’를 표현해야 한다.
  3. 변화는 즉시 반영하거나 일괄 반영 중 하나로 통일해야 한다.

    • 원판 돌리기처럼 여러 단계의 변화를 다루는 문제에서는 “시점 통제”가 가장 중요하다.
  4. 시뮬레이션은 디버깅 중심의 문제다.

    • 논리적 실수보다는 구현 순서, 조건 누락, 오프셋 계산 오류가 주된 원인이다.

7. 결론

시뮬레이션 문제는 “상태의 변화”를 코드로 재현하는 문제다.
문제의 본질은 복잡하지 않지만, 구현 과정에서 정확한 제어 흐름과 세밀한 조건 처리가 요구된다.

  • 스위치 켜고 끄기: 단일 명령 반복 구조
  • 빗물: 구조적 시각화 중심
  • 원판 돌리기: 다단계 상태 전이

이 세 문제는 각각 시뮬레이션의 기본, 확장, 복합 형태를 잘 보여준다.
즉, 시뮬레이션 문제를 잘 다루려면 “상태를 코드로 표현하고 조작하는 감각”이 필요하다.

이 감각이 익숙해지면, 단순 구현 문제를 넘어서
복잡한 게임 로직, 프로세스 시뮬레이션, 동적 상태 제어 문제에도 자연스럽게 응용할 수 있다.

profile
성용의 프로그래밍 블로그

0개의 댓글