알고리즘 문제 풀이/Programers

[프로그래머스 Lv.2 / C#] 미로탈출_BFS

Ardmos :) 2025. 1. 12. 21:16

BFS 문제. 프로그래머스 C# 버전 문제로 튜플 사용 방법을 신경써야한다

using System;
using System.Collections;
using System.Collections.Generic;

public class Solution {
 public int solution(string[] maps)
{
    int answer = 0;
    int startToLever = 0;
    int leverToExit = 0;
    //Tuple<int, int> startPos = new Tuple<int, int>(0,0);
    //Tuple<int, int> leverPos = new Tuple<int, int>(0, 0);
    //Tuple<int, int> exitPos = new Tuple<int, int>(0, 0);
    (int x, int y) startPos = (0, 0);
    (int x, int y) leverPos = (0, 0);
    (int x, int y) exitPos = (0, 0);

    // 1. 시작위치, 레버위치, 탈출위치부터 찾아야함
    for (int y=0; y<maps.Length; y++)
    {
        string row = maps[y];

        for(int x=0; x<row.Length; x++)
        {
            switch (row[x])
            {
                case 'S':
                    startPos = (x, y);
                    break;
                case 'L':
                    leverPos = (x, y);
                    break;
                case 'E':
                    exitPos = (x, y);
                    break;
            }
        }
    }
    //Debug.Log($"startPos:{startPos}, leverPos:{leverPos}, exitPos:{exitPos}");

    // 2. 시작위치 -> 레버위치 검색 시도. 불가능하면 끝, 성공하면 다음 단계
    startToLever = BFS(maps, startPos, leverPos);
    if (startToLever == -1) return -1;


    // 3. 레버위치 -> 탈출위치 검색 시도.
    leverToExit = BFS(maps, leverPos, exitPos);
    if (leverToExit == -1) return -1;


    //Debug.Log($"answer:{answer}, startToLever:{startToLever}, leverToExit:{leverToExit}");
    // 4. 최종 이동거리 구하기
    answer = startToLever + leverToExit;

    return answer;
}


private int BFS(string[] maps, (int x, int y)startPos, (int x, int y) destinationPos)
{
    int[] dx = new int[] { -1, 1, 0, 0 };
    int[] dy = new int[] { 0, 0, -1, 1 };
    int mapRowCount = maps.Length;
    int mapColumnCount = maps[0].Length;
    int[,] distance = new int[mapColumnCount, mapRowCount];
    Queue<(int x, int y)> movingQueue = new Queue<(int x, int y)>();

    // 시작지점 인큐, 이동거리 초기화
    movingQueue.Enqueue(startPos);
    distance[startPos.x, startPos.y] = 0;

    // BFS 탐색 시작
    while (movingQueue.Count > 0)
    {
        (int x, int y) currentPos = movingQueue.Dequeue();

        // 목표지점 도달했는지 확인
        if (currentPos.x == destinationPos.x && currentPos.y == destinationPos.y)
        {
            return distance[currentPos.x, currentPos.y];
        }

        // 사방 검색 시작
        for (int i = 0; i < 4; i++)
        {
            (int x, int y) nextPos = (currentPos.x + dx[i], currentPos.y + dy[i]);

            // 새로운 다음 위치 유효성 검증
            if (nextPos.x >= 0 && nextPos.x < mapColumnCount
                && nextPos.y >= 0 && nextPos.y < mapRowCount
                && maps[nextPos.y][nextPos.x] != 'X'
                && distance[nextPos.x, nextPos.y] == 0)
            {
                // 유효한 위치라면 이동처리
                movingQueue.Enqueue(nextPos);
                distance[nextPos.x, nextPos.y] = distance[currentPos.x, currentPos.y] + 1;
            }
        }
    }

    return -1;
}
}
728x90