RiseOJ는 solved.ac와 제휴 관계가 없습니다. 티어 아이콘 © solved.ac. solved.ac
← 브론즈 II

시뮬레이션 기초

문제가 시키는 과정을 그대로 코드로 옮기는 연습.

기초 & 구현 Bronze II 브론즈 II
선수 지식: 2차원 배열
1강 시뮬레이션의 개념: 시키는 대로 공식

시뮬레이션이란?

시뮬레이션(simulation) 은 문제가 묘사하는 과정을 그대로 코드로 옮겨 따라
하는 풀이법입니다. 똑똑한 수식이나 알고리즘 대신, "시키는 대로 정확히 흉내 내기"가
핵심입니다.


1. 시뮬레이션의 마음가짐

별다른 통찰이 없어도 됩니다. 대신 문제의 규칙을 빠짐없이, 순서대로 코드로
재현해야 합니다. 그래서 "독해력 + 꼼꼼함"이 실력입니다.

예: "로봇이 명령 문자열을 따라 격자 위를 움직인다. 마지막 위치를 출력하라."

명령: 'U'=위, 'D'=아래, 'L'=왼, 'R'=오른쪽
시작 (0,0)에서 명령을 하나씩 따라간다.

2. 상태를 변수로 들고 갱신

시뮬레이션은 "현재 상태"를 변수에 들고, 각 단계마다 갱신하는 구조입니다.

int x = 0, y = 0;            // 현재 위치(상태)
string cmd; cin >> cmd;
for (char c : cmd) {
    if (c == 'U') y++;
    else if (c == 'D') y--;
    else if (c == 'L') x--;
    else if (c == 'R') x++;
}
cout << x << ' ' << y << '\n';

상태(여기선 위치 x,y)를 정확히 정의하고, 각 입력에 따라 어떻게 바뀌는지만
적으면 됩니다.


3. 방향 배열로 깔끔하게

상하좌우 같은 이동은 방향 배열로 표현하면 조건문이 줄어듭니다.

// 예: 0=북, 시계방향. 회전은 dir = (dir+1)%4
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};

회전·이동이 섞인 문제(달팽이 채우기 등)에서 특히 유용합니다.


4. 어떻게 알아보나

다음 특징이 보이면 시뮬레이션 문제입니다.

  • "다음 규칙에 따라 ~를 반복한다", "이 과정을 따라가라".
  • 명령/턴/단계가 순서대로 주어진다.
  • 영리한 공식보다 과정 재현이 자연스럽다.

복잡도

단계 수 \(\times\) 한 단계 비용입니다. 보통 그대로 따라 해도 충분하지만, 단계가
아주 많으면(예: \(10^9\)번 반복) 주기를 찾아 건너뛰는 최적화가 필요할 수 있습니다.


정리

  • 시뮬레이션 = 문제의 과정을 그대로 흉내 내기.
  • "현재 상태"를 변수로 들고 단계마다 갱신.
  • 이동/회전은 방향 배열로 깔끔하게.
  • 똑똑함보다 정확한 독해와 꼼꼼함이 핵심.
2강 시뮬레이션 구현과 연습 공식

시뮬레이션 구현 레퍼런스

대표 시뮬레이션 패턴 — 로봇 이동, 격자 채우기, 회전 — 을 코드로 정리하고
함정을 짚습니다.


1. 격자 위 이동 + 경계 처리

int n, m; cin >> n >> m;     // 격자 크기
int x = 0, y = 0;            // 현재 칸
string cmd; cin >> cmd;
int dx[4]={-1,1,0,0}, dy[4]={0,0,-1,1};  // U D L R
for (char c : cmd) {
    int d = (c=='U')?0 : (c=='D')?1 : (c=='L')?2 : 3;
    int nx = x + dx[d], ny = y + dy[d];
    if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;  // 벽이면 제자리
    x = nx; y = ny;
}
cout << x << ' ' << y << '\n';
n, m = map(int, input().split())
x = y = 0
cmd = input()
d = {'U':(-1,0),'D':(1,0),'L':(0,-1),'R':(0,1)}
for c in cmd:
    nx, ny = x + d[c][0], y + d[c][1]
    if 0 <= nx < n and 0 <= ny < m:
        x, y = nx, ny
print(x, y)

"벽을 만나면 무시(제자리)" 같은 규칙을 문제에서 정확히 읽어 반영해야 합니다.


2. 달팽이 격자 채우기 (회전)

방향을 두고, 막히면 시계 방향으로 꺾습니다.

int a[100][100] = {0};
int dx[4]={0,1,0,-1}, dy[4]={1,0,-1,0};  // 우 하 좌 상
int x=0, y=0, dir=0;
for (int v = 1; v <= n*n; v++) {
    a[x][y] = v;
    int nx = x+dx[dir], ny = y+dy[dir];
    if (nx<0||nx>=n||ny<0||ny>=n||a[nx][ny]!=0) {  // 벽이거나 이미 찬 칸
        dir = (dir+1) % 4;                          // 방향 전환
        nx = x+dx[dir]; ny = y+dy[dir];
    }
    x = nx; y = ny;
}

(dir+1)%4로 방향을 순환시키는 게 핵심(나머지 연산 활용).


3. 함정과 패턴 인식

  • 규칙 누락 — 문제의 모든 조건(벽 처리, 우선순위 등)을 빠짐없이 반영.
  • 상태 정의 부족 — 위치 외에 방향·점수·시간 등 추가 상태가 필요할 수 있음.
  • 경계 검사 — 격자 밖 접근은 런타임 에러. 이동 전에 항상 검사.
  • 인덱스 1-based/0-based — 문제 좌표와 배열 인덱스를 일치시키기.

문제에 "다음 규칙대로 반복", "로봇/주사위/컨베이어", "격자를 채워라", "턴을
진행한다"
같은 말이 보이면 시뮬레이션입니다.


정리

시뮬레이션 구현의 핵심은 (1) 상태(위치·방향 등)를 변수로 명확히, (2) 방향 배열과
%로 이동·회전, (3) 매 단계 경계·규칙 검사입니다. 어려운 통찰보다 문제를 천천히
정확하게 읽는 것
이 가장 큰 무기입니다.