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