프로그래머스 - C#
8. 프로그래머스 - 여행경로
seqw
2023. 5. 31. 17:42
문제 설명 주어진 항공권을 모두 이용하여 여행경로를 짜려고 합니다. 항상 "ICN" 공항에서 출발합니다. 항공권 정보가 담긴 2차원 배열 tickets가 매개변수로 주어질 때, 방문하는 공항 경로를 배열에 담아 return 하도록 solution 함수를 작성해주세요. - 모든 공항은 알파벳 대문자 3글자로 이루어집니다. - 주어진 공항 수는 3개 이상 10,000개 이하입니다. - tickets의 각 행 [a, b]는 a 공항에서 b 공항으로 가는 항공권이 있다는 의미입니다. - 주어진 항공권은 모두 사용해야 합니다. - 만일 가능한 경로가 2개 이상일 경우 알파벳 순서가 앞서는 경로를 return 합니다. - 모든 도시를 방문할 수 없는 경우는 주어지지 않습니다. Tickets : [["ICN", "JFK"], ["HND", "IAD"], ["JFK", "HND"]] return : ["ICN", "JFK", "HND", "IAD"] |
문제 해결 1. 티켓을 정렬, 같은 출발지를 가진 도착지를 이름순으로 정렬한다. 2. DFS로 검색을 시작. 검색한 티켓은 검색체크 활성화 3. 체크가 활성화된 티켓은 다시 검색하지 않음 4. 깊게 검색하다 모든 티켓을 사용하지 않았는데 더 갈곳이 없다면 검색체크를 비활성화 하면서 해당 검색 종료 5. 아직 검색할게 남은 지역까지 비활성화하면서 계속 뒤로 가다가 검색할게 남은 다른 지역 검색 6. 모든 지역을 검색했다면 종료 |
Dictionary<string, List<Tuple<string, int>>> dicTic = new Dictionary<string, List<Tuple<string, int>>>();
List<string> answer = new List<string>();
bool[] isChecks;
int ticketCount;
public string[] solution(string[,] tickets)
{
ticketCount = tickets.Length / 2;
isChecks = new bool[ticketCount];
//세팅
for (int i = 0; i < ticketCount; ++i)
{
if (dicTic.TryGetValue(tickets[i, 0], out List<Tuple<string, int>> item))
{
item.Add(new Tuple<string, int>(tickets[i, 1], i));
item.Sort((item1, item2) => item1.Item1.CompareTo(item2.Item1));
}
else
{
dicTic.Add(tickets[i, 0], new List<Tuple<string, int>>() { new Tuple<string, int>(tickets[i, 1], i) });
}
}
//검색 시작
if (DFS("ICN", 0, ref tickets))
{
answer.Add("ICN");
}
//저장된거 역전한뒤 리턴
answer.Reverse();
return answer.ToArray();
}
public bool DFS(string name, int count, ref string[,] tickets)
{
// 티켓을 전부 사용했다면 종료
if (count == ticketCount)
{
return true;
}
// 검색
else if(dicTic.TryGetValue(name,out List<Tuple<string, int>> list))
{
bool isCheck = false;
foreach (var item in list)
{
// 이미 함 갔던 곳이라면 패스
if (isChecks[item.Item2])
{
continue;
}
// 가지 않았던 곳만 쳌
else
{
isChecks[item.Item2] = true;
if (DFS(item.Item1, count + 1, ref tickets))
{
answer.Add(item.Item1);
isCheck = true;
break;
}
else
{
isChecks[item.Item2] = false;
}
}
}
return isCheck;
}
return false;
}
상당히 애먹었다. 티켓들을 정렬하고 DFS로 최대한 적게 빠른 길을 찾으려 했는데 꽤 많은 시행착오를 겪었다.
결국 완성한 코드도 그렇게 좋다고 말하기 애매한 완성도고...
특히 1번 테스트케이스가 날 그렇게나 괴롭혔는데 알고보니 중복 티켓에 대한 처리에 관련된 문제였다.
그리고 버전 차이인지 Dictionary<string, List<(string, int)>> 요게 안된다.