전체 코드

#include <iostream>
#include <iomanip>  
using namespace std;

const int MAX = 100;
int board[MAX][MAX] = {};
int N;

enum DIR { RIGHT = 0, DOWN = 1, LEFT = 2, UP = 3 };

void PrintBoard() {
    for (int y = 0; y < N; y++) {
        for (int x = 0; x < N; x++) {
            cout << setfill('0') << setw(2) << board[y][x] << " ";
        }
        cout << endl;
    }
}

bool CanGo(int nx, int ny) {
    if (nx < 0 || nx >= N || ny < 0 || ny >= N || board[nx][ny] != 0) 
        return false;
    return true;
}

void SetBoard() {
    int dir = RIGHT;
    int num = 1;
    int x = 0, y = 0;
    int dx[4] = {1, 0, -1, 0};
    int dy[4] = {0, 1, 0, -1};

    while (true) {
        board[y][x] = num;
        if (num == N * N) break;

        int next_x = x + dx[dir];
        int next_y = y + dy[dir];

        if (CanGo(next_x, next_y)) {
            x = next_x;
            y = next_y;
            num++;
        } else {
            dir = (dir + 1) % 4;
        }
    }
}

int main() {
    cin >> N;
    SetBoard();
    PrintBoard();
    return 0;
}

**📌 달팽이 문제

✅ 문제 개요

  • 주어진 N × N 크기의 보드에 1부터 N × N까지 숫자를 달팽이(나선) 모양으로 채워 넣는 문제
  • 숫자는 오른쪽 → 아래 → 왼쪽 → 위 순서로 채워짐
  • 경계에 닿거나 이미 숫자가 채워진 칸을 만나면 다음 방향으로 전환해야 함

📍 입력 예시

5

📍 출력 예시

01 02 03 04 05
16 17 18 19 06
15 24 25 20 07
14 23 22 21 08
13 12 11 10 09

📌 1. 문제 해결 접근 방식

1️⃣ 보드 생성

  • 2차원 배열 board[N][N]을 선언하여 숫자를 채워 넣음
  • N을 입력받아 보드 크기를 결정

2️⃣ 이동 방향 설정

  • 네 가지 방향: 오른쪽 → 아래 → 왼쪽 → 위
  • 방향을 배열로 관리하여 쉽게 전환 가능
    dx[] = {1, 0, -1, 0};  // X축 이동 (오른쪽, 아래, 왼쪽, 위)
    dy[] = {0, 1, 0, -1};  // Y축 이동 (오른쪽, 아래, 왼쪽, 위)

3️⃣ 이동 가능 여부 체크

  • 이동할 위치 (nextX, nextY)
    • 배열 범위를 벗어나지 않고
    • 아직 숫자가 채워지지 않은 칸인지
    • board[nextX][nextY] == 0 이면 이동 가능

4️⃣ 방향 전환

  • 만약 이동이 불가능하면, 다음 방향으로 변경
  • 방향은 (dir + 1) % 4를 사용하여 순환 처리

📌 2. 코드 분석

📌 2.1 상수 및 변수 선언

#include <iostream>
#include <iomanip>  // 숫자 두 자리로 포맷
using namespace std;

const int MAX = 100;  // 보드의 최대 크기 (100x100)
int board[MAX][MAX] = {};  // 2차원 배열 (초기값 0)
int N;  // 보드 크기

📍 설명

  • MAX = 100: 보드 최대 크기 설정 (메모리 효율 고려)
  • board[MAX][MAX]: 100x100 배열을 선언, 초기값은 0
  • N: 사용자 입력을 받아 보드 크기를 결정

📌 2.2 방향 열거형 정의

enum DIR {
    RIGHT = 0,  // → 오른쪽
    DOWN = 1,   // ↓ 아래
    LEFT = 2,   // ← 왼쪽
    UP = 3      // ↑ 위
};

📍 설명

  • enum을 사용하여 방향을 숫자로 표현
  • 각 숫자는 배열 인덱스로 활용됨

📌 2.3 보드 출력 함수

void PrintBoard() {
    for (int y = 0; y < N; y++) {
        for (int x = 0; x < N; x++) {
            cout << setfill('0') << setw(2) << board[y][x] << " ";
        }
        cout << endl;
    }
}

📍 설명

  • 이중 반복문을 사용하여 보드의 숫자를 출력
  • setfill('0') << setw(2): 숫자를 두 자리(01, 02)로 출력
  • endl을 사용하여 줄바꿈 처리

📌 2.4 이동 가능 여부 확인 함수

bool CanGo(int nx, int ny) {
    if (nx < 0 || nx >= N) return false;  // X 범위 초과
    if (ny < 0 || ny >= N) return false;  // Y 범위 초과
    if (board[nx][ny] != 0) return false; // 이미 숫자가 채워짐
    return true;
}

📍 설명

  • (nx, ny) 좌표가 보드 범위를 벗어나면 false
  • board[nx][ny] != 0 → 이미 숫자가 있는 경우 false
  • 모든 조건을 만족하면 true 반환

📌 2.5 보드 숫자 채우기 함수

void SetBoard() {
    int dir = RIGHT;  // 초기 방향: 오른쪽
    int num = 1;  // 채울 숫자
    int x = 0, y = 0;  // 시작 위치 (0, 0)

    int dx[4] = {1, 0, -1, 0};  // X축 이동 (→ ↓ ← ↑)
    int dy[4] = {0, 1, 0, -1};  // Y축 이동 (→ ↓ ← ↑)

    while (true) {
        board[y][x] = num;  // 현재 위치에 숫자 채우기

        if (num == N * N) break;  // 마지막 숫자 도달 시 종료

        int next_x = x + dx[dir];  // 다음 X 좌표
        int next_y = y + dy[dir];  // 다음 Y 좌표

        if (CanGo(next_x, next_y)) {  
            x = next_x;
            y = next_y;
            num++;
        }
        else {
            dir = (dir + 1) % 4;  // 이동 불가능하면 방향 전환
        }
    }
}

📍 설명

  • num = 1부터 시작하여 순차적으로 보드에 채워 넣음
  • (next_x, next_y)를 계산하여 이동 가능 여부 확인
  • 이동할 수 있으면 좌표 갱신, 숫자 증가
  • 이동이 불가능하면 (dir + 1) % 4를 사용하여 다음 방향으로 전환

📌 2.6 main() 함수

int main() {
    cin >> N;  // 보드 크기 입력받기
    SetBoard();  // 보드 숫자 채우기
    PrintBoard();  // 결과 출력
    return 0;
}

📍 설명

  • cin >> N;을 통해 보드 크기를 입력받음
  • SetBoard()를 호출하여 달팽이 모양으로 숫자를 채움
  • PrintBoard()를 호출하여 완성된 보드를 출력

profile
李家네_공부방

0개의 댓글