Skip to content
Home » 길 찾기 게임 | [썩쏘Tv]신박한 길찾기 게임 Grow Maze 최근 답변 101개

길 찾기 게임 | [썩쏘Tv]신박한 길찾기 게임 Grow Maze 최근 답변 101개

당신은 주제를 찾고 있습니까 “길 찾기 게임 – [썩쏘TV]신박한 길찾기 게임 GROW MAZE“? 다음 카테고리의 웹사이트 https://kk.taphoamini.com 에서 귀하의 모든 질문에 답변해 드립니다: https://kk.taphoamini.com/wiki/. 바로 아래에서 답을 찾을 수 있습니다. 작성자 썩쏘TV 이(가) 작성한 기사에는 조회수 125,649회 및 좋아요 320개 개의 좋아요가 있습니다.

길 찾기 게임 주제에 대한 동영상 보기

여기에서 이 주제에 대한 비디오를 시청하십시오. 주의 깊게 살펴보고 읽고 있는 내용에 대한 피드백을 제공하세요!

d여기에서 [썩쏘TV]신박한 길찾기 게임 GROW MAZE – 길 찾기 게임 주제에 대한 세부정보를 참조하세요

이게임은 길찾기 게임 Grow Maze 입니다
어려웠습니다..
http://afreeca.com/ehdwo5139 여기는 제방송국 입니다
구독 감사합니다

길 찾기 게임 주제에 대한 자세한 내용은 여기를 참조하세요.

길 찾기 게임 – 코딩테스트 연습 – 프로그래머스 스쿨

길 찾기 게임. 전무로 승진한 라이언은 기분이 너무 좋아 프렌즈를 이끌고 특별 휴가를 가기로 했다. 내친김에 여행 계획까지 구상하던 라이언은 재미있는 게임을 생각 …

+ 여기에 표시

Source: school.programmers.co.kr

Date Published: 8/22/2021

View: 5526

구글맵 탈출게임 MAP CRUNCH – 네이버 블로그

오직 직감으로 길을 걸어봅니다. 길 모른 땐 일단 오른쪽으로 고고. 왜냐하면 지구는 둥그니깐?? 이왕이면 관광지로 보내주던가. 게임일 뿐이지만.

+ 여기를 클릭

Source: m.blog.naver.com

Date Published: 8/25/2021

View: 5494

프로그래머스 길 찾기 게임 – velog

프로그래머스 길 찾기 게임 (어제보다 나아지는 오늘) … 그냥 지도를 주고 게임을 시작하면 재미가 덜해지므로, 라이언은 방문할 곳의 2차원 좌표 …

+ 여기에 표시

Source: velog.io

Date Published: 9/5/2021

View: 3697

[프로그래머스] 길 찾기 게임 Java 풀이 – 작은 한걸음 – 티스토리

[프로그래머스] 길 찾기 게임 Java 풀이 … 그냥 지도를 주고 게임을 시작하면 재미가 덜해지므로, 라이언은 방문할 곳의 2차원 좌표 값을 구하고 각 …

+ 여기에 더 보기

Source: small-stap.tistory.com

Date Published: 7/22/2022

View: 9831

[ 프로그래머스 길 찾기 게임 (Lv3) ] (C++) – 얍문 – 티스토리

프로그래머스의 길찾기게임(Lv3) 문제이다. [ 문제풀이 ]. 트리가 주어졌을 때, 해당 트리의 전위순회와 후위순회 순서를 구해야 하는 문제이다.

+ 여기에 표시

Source: yabmoons.tistory.com

Date Published: 6/22/2022

View: 694

[프로그래머스] 길 찾기 게임(Python, Java) – 지혜로운 개발로그

길 찾기 게임. 전무로 승진한 라이언은 기분이 너무 좋아 프렌즈를 이끌고 특별 휴가를 가기로 했다. 내친김에 여행 계획까지 구상하던 라이언은 …

+ 여기에 자세히 보기

Source: wiselog.tistory.com

Date Published: 5/8/2022

View: 7885

길 찾기 게임 – 오뚝이개발자 – 티스토리

나의 풀이. preorder와 postorder로 트리를 순회하는 것은 쉽다.(모르면 검색을 해보면 금방 나올 것이다.) 이 문제의 핵심은 주어진 정보로 트리를 …

+ 여기에 자세히 보기

Source: otugi.tistory.com

Date Published: 7/4/2022

View: 7191

[프로그래머스]길 찾기 게임 – JAVA – 빈둥벤둥 IT logging

입력받은 데이터를 가지고 트리를 만들고, 전위순회/후위순회한 결과를 반환하면 된다. 트리에 대해 잘 알고 있었다면 크게 어려움 없이 풀 수 있는 문제 …

+ 여기에 표시

Source: moonsbeen.tistory.com

Date Published: 9/16/2021

View: 9411

[C++] 프로그래머스 길 찾기 게임 풀이

코딩테스트 연습 – 길 찾기 게임 … 따라서 각 노드의 번호를 통해 좌표를 쉽게 찾기 위해 map을 사용하였고 전위 순회 방식으로 노드를 정렬하기 …

+ 여기를 클릭

Source: shyeon.tistory.com

Date Published: 6/2/2021

View: 8555

주제와 관련된 이미지 길 찾기 게임

주제와 관련된 더 많은 사진을 참조하십시오 [썩쏘TV]신박한 길찾기 게임 GROW MAZE. 댓글에서 더 많은 관련 이미지를 보거나 필요한 경우 더 많은 관련 기사를 볼 수 있습니다.

[썩쏘TV]신박한 길찾기 게임 GROW MAZE
[썩쏘TV]신박한 길찾기 게임 GROW MAZE

주제에 대한 기사 평가 길 찾기 게임

  • Author: 썩쏘TV
  • Views: 조회수 125,649회
  • Likes: 좋아요 320개
  • Date Published: 2014. 1. 22.
  • Video Url link: https://www.youtube.com/watch?v=_r9WQc67qCI

구글맵 탈출게임 MAP CRUNCH

아무리 게임이지만

280곳을 돌아다녔는데

관광지는 안 보내주고

허허벌판만 보내고 너무 외롭다

그보다 집에 갈 수 있긴 한 걸까

이 게임에 끝이 있긴 한걸까ㅠㅠ

나의 한계와 게임이해도가 떨어짐을

확인하고 팁을 써보기로 한다

프로그래머스 길 찾기 게임

🙂 문제 – 길찾기 게임

✔️ 문제 내용

전무로 승진한 라이언은 기분이 너무 좋아 프렌즈를 이끌고 특별 휴가를 가기로 했다.

내친김에 여행 계획까지 구상하던 라이언은 재미있는 게임을 생각해냈고 역시 전무로 승진할만한 인재라고 스스로에게 감탄했다. 라이언이 구상한(그리고 아마도 라이언만 즐거울만한) 게임은, 카카오 프렌즈를 두 팀으로 나누고, 각 팀이 같은 곳을 다른 순서로 방문하도록 해서 먼저 순회를 마친 팀이 승리하는 것이다.

그냥 지도를 주고 게임을 시작하면 재미가 덜해지므로, 라이언은 방문할 곳의 2차원 좌표 값을 구하고 각 장소를 이진트리의 노드가 되도록 구성한 후, 순회 방법을 힌트로 주어 각 팀이 스스로 경로를 찾도록 할 계획이다.

라이언은 아래와 같은 특별한 규칙으로 트리 노드들을 구성한다. 트리를 구성하는 모든 노드의 x, y 좌표 값은 정수이다.

모든 노드는 서로 다른 x값을 가진다.

같은 레벨(level)에 있는 노드는 같은 y 좌표를 가진다.

자식 노드의 y 값은 항상 부모 노드보다 작다.

임의의 노드 V의 왼쪽 서브 트리(left subtree)에 있는 모든 노드의 x값은 V의 x값보다 작다.

임의의 노드 V의 오른쪽 서브 트리(right subtree)에 있는 모든 노드의 x값은 V의 x값보다 크다. 아래 예시를 확인해보자.

라이언의 규칙에 맞게 이진트리의 노드만 좌표 평면에 그리면 다음과 같다. (이진트리의 각 노드에는 1부터 N까지 순서대로 번호가 붙어있다.)

이제, 노드를 잇는 간선(edge)을 모두 그리면 아래와 같은 모양이 된다.

위 이진트리에서 전위 순회(preorder), 후위 순회(postorder)를 한 결과는 다음과 같고, 이것은 각 팀이 방문해야 할 순서를 의미한다. 전위 순회 : 7, 4, 6, 9, 1, 8, 5, 2, 3

후위 순회 : 9, 6, 5, 8, 1, 4, 3, 2, 7 다행히 두 팀 모두 머리를 모아 분석한 끝에 라이언의 의도를 간신히 알아차렸다.

그러나 여전히 문제는 남아있다. 노드의 수가 예시처럼 적다면 쉽게 해결할 수 있겠지만, 예상대로 라이언은 그렇게 할 생각이 전혀 없었다.

이제 당신이 나설 때가 되었다.

곤경에 빠진 카카오 프렌즈를 위해 이진트리를 구성하는 노드들의 좌표가 담긴 배열 nodeinfo가 매개변수로 주어질 때,

노드들로 구성된 이진트리를 전위 순회, 후위 순회한 결과를 2차원 배열에 순서대로 담아 return 하도록 solution 함수를 완성하자.

❌ 제한사항

nodeinfo는 이진트리를 구성하는 각 노드의 좌표가 1번 노드부터 순서대로 들어있는 2차원 배열이다.

nodeinfo의 길이는 1 이상 10,000 이하이다.

nodeinfo[i] 는 i + 1번 노드의 좌표이며, [x축 좌표, y축 좌표] 순으로 들어있다.

모든 노드의 좌표 값은 0 이상 100,000 이하인 정수이다.

트리의 깊이가 1,000 이하인 경우만 입력으로 주어진다.

모든 노드의 좌표는 문제에 주어진 규칙을 따르며, 잘못된 노드 위치가 주어지는 경우는 없다.

🖐풀이 방법

프로그래머스에서 LEVEL 3로 되어있다.

먼저 문제에 나온 전위순회와 후위 순회에 대해 알아보아야 한다. * 전위 순회는 [루트 – 왼쪽 자식 – 오른쪽 자식] 순으로 순회합니다. * 중위 순회는 [왼쪽 자식 – 루트 – 오른쪽 자식] 순으로 순회합니다. * 후위 순회는 [왼쪽 자식 – 오른쪽 자식 – 루트] 순으로 순회합니다. 주어진 값을 어떻게 2진 트리와 같은 형식으로 나타낼까? 라는 생각을 해보았는데 아래와 같은 생각이 들었다. * 주어진 수 중 Y축이 가장 큰 것은 가장 최상단 root이다. (가장 위에 있으므로) * 주어진 수 중 X축이 가장 작은 것은 최 왼쪽 / 가장 큰 것은 최 오른쪽에 있다고 생각할 수 있다. * 그러면 가장 큰 Y값을 찾아서 root node로 두고 해당 node에 왼쪽과 오른쪽을 x가 자신의 x보다 큰가 작은가로 나누어 줄 수 있다. * 만일 둘중에 자식 노드가 없다면 해당 node는 마지막 노드가 되는 것이다. * node class를 만들어서 위의 조건에 맞게 root node의 x를 기준으로 나누어 주면 이진 트리가 될 수 있다. 이렇게 나누어진 class를 기준으로 전위 순회와 후위 순회를 처리해주면 된다.

📃 CODE

[프로그래머스] 길 찾기 게임 Java 풀이

걸음마 개발자

이 글은 혼자 학습한 내용을 바탕으로 작성되었습니다.

틀리거나 잘못된 정보가 있을 수 있습니다.

댓글로 알려주시면 수정하도록 하겠습니다.

1. 문제

전무로 승진한 라이언은 기분이 너무 좋아 프렌즈를 이끌고 특별 휴가를 가기로 했다.

내친김에 여행 계획까지 구상하던 라이언은 재미있는 게임을 생각해냈고 역시 전무로 승진할만한 인재라고 스스로에게 감탄했다.

라이언이 구상한(그리고 아마도 라이언만 즐거울만한) 게임은, 카카오 프렌즈를 두 팀으로 나누고, 각 팀이 같은 곳을 다른 순서로 방문하도록 해서 먼저 순회를 마친 팀이 승리하는 것이다.

그냥 지도를 주고 게임을 시작하면 재미가 덜해지므로, 라이언은 방문할 곳의 2차원 좌표 값을 구하고 각 장소를 이진트리의 노드가 되도록 구성한 후, 순회 방법을 힌트로 주어 각 팀이 스스로 경로를 찾도록 할 계획이다.

라이언은 아래와 같은 특별한 규칙으로 트리 노드들을 구성한다.

트리를 구성하는 모든 노드의 x, y 좌표 값은 정수이다.

모든 노드는 서로 다른 x값을 가진다.

같은 레벨(level)에 있는 노드는 같은 y 좌표를 가진다.

자식 노드의 y 값은 항상 부모 노드보다 작다.

임의의 노드 V의 왼쪽 서브 트리(left subtree)에 있는 모든 노드의 x값은 V의 x값보다 작다.

임의의 노드 V의 오른쪽 서브 트리(right subtree)에 있는 모든 노드의 x값은 V의 x값보다 크다.

아래 예시를 확인해보자.

라이언의 규칙에 맞게 이진트리의 노드만 좌표 평면에 그리면 다음과 같다. (이진트리의 각 노드에는 1부터 N까지 순서대로 번호가 붙어있다.)

이제, 노드를 잇는 간선(edge)을 모두 그리면 아래와 같은 모양이 된다.

위 이진트리에서 전위 순회(preorder), 후위 순회(postorder)를 한 결과는 다음과 같고, 이것은 각 팀이 방문해야 할 순서를 의미한다.

전위 순회 : 7, 4, 6, 9, 1, 8, 5, 2, 3

후위 순회 : 9, 6, 5, 8, 1, 4, 3, 2, 7

다행히 두 팀 모두 머리를 모아 분석한 끝에 라이언의 의도를 간신히 알아차렸다.

그러나 여전히 문제는 남아있다. 노드의 수가 예시처럼 적다면 쉽게 해결할 수 있겠지만, 예상대로 라이언은 그렇게 할 생각이 전혀 없었다.

이제 당신이 나설 때가 되었다.

곤경에 빠진 카카오 프렌즈를 위해 이진트리를 구성하는 노드들의 좌표가 담긴 배열 nodeinfo가 매개변수로 주어질 때,

노드들로 구성된 이진트리를 전위 순회, 후위 순회한 결과를 2차원 배열에 순서대로 담아 return 하도록 solution 함수를 완성하자.

2. 입력

nodeinfo는 이진트리를 구성하는 각 노드의 좌표가 1번 노드부터 순서대로 들어있는 2차원 배열이다. nodeinfo의 길이는 1 이상 10,000 이하이다. nodeinfo [i]는 i + 1번 노드의 좌표이며, [x축 좌표, y축 좌표] 순으로 들어있다. 모든 노드의 좌표 값은 0 이상 100,000 이하인 정수이다. 트리의 깊이가 1,000 이하인 경우만 입력으로 주어진다. 모든 노드의 좌표는 문제에 주어진 규칙을 따르며, 잘못된 노드 위치가 주어지는 경우는 없다.

3. 예제

node inforesult [[5,3],[11,5],[13,3],[3,5],[6,1],[1,3],[8,6],[7,2],[2,2]] [[7,4,6,9,1,8,5,2,3],[9,6,5,8,1,4,3,2,7]]

4. 풀이

public class Node{ private final int x; private final int number; private Node left; private Node right; public Node(int x, int number){ this.x = x; this.number = number; this.left = null; this.right = null; } }

먼저 트리를 구성해야 하므로 Node객체를 만들어 해당 Node의 왼쪽과 오른쪽에 자식 Node 객체를 가지도록 만들겠습니다. 또한 X축의 값의 비교를 통해 왼쪽과 오른쪽을 결정해야 하므로 X좌표의 값도 가지며 Node의 번호도 가지도록 Class를 구성합니다.

PriorityQueue queue = new PriorityQueue<>((o1, o2) -> { if(o1[1] == o2[1]) return Integer.compare(o2[0], o1[0]); else return Integer.compare(o2[1], o1[1]); }); for(int i=0; i preAnswer = new LinkedList<>(); preOrder(root, preAnswer); List postAnswer = new LinkedList<>(); postOrder(root, postAnswer); return new int[][]{preAnswer.stream().mapToInt(Integer::intValue).toArray(), postAnswer.stream().mapToInt(Integer::intValue).toArray()}; ————————————————————————————– public void preOrder(Node node, List answer){ if(node != null){ answer.add(node.number); preOrder(node.left, answer); preOrder(node.right, answer); } } public void postOrder(Node node, List answer){ if (node != null) { postOrder(node.left, answer); postOrder(node.right, answer); answer.add(node.number); } }

이제 해당 트리를 통해 전위 순회와 후위 순회를 통해 만들어진 값을 2차원 배열로 만들어 반환하면 문제를 풀 수 있습니다.

5. 코드

전체 코드는 Git에 있습니다.

[ 프로그래머스 길 찾기 게임 (Lv3) ] (C++)

프로그래머스의 길찾기게임(Lv3) 문제이다.

[ 문제풀이 ]

트리가 주어졌을 때, 해당 트리의 전위순회와 후위순회 순서를 구해야 하는 문제이다.

문제를 단계별로 한 단계씩 알아가보자.

#1. Node관리

이 문제는 트리의 Node들을 가지고 과정을 진행하고 정답을 도출해 내야 하는 문제이다.

따라서, Node들을 관리하기 위해서 본인은 구조체를 하나 정의해 주었다.

그럼 ! 구조체에 필요한 멤버변수들을 뭐가 있을지 생각을 해보자.

1. 해당 Node의 (x , y)좌표 정보가 필요할 것이다.

2. 해당 Node의 번호가 필요할 것이다.

– 번호가 필요한 이유는 정답 도출을 위해서이다. 전위든 후위든 결국 그 순서를 Node의 번호 순서대로 출력을 해야 하

는데 이를 위해서 Node의 번호 또한 우리가 알고 있어야 할 정보 중에 하나가 된다.

3. 자식 Node에 대한 정보가 필요할 것이다.

– Tree구조로 진행되므로, 해당 Node의 왼쪽 자식에 대한 정보, 오른쪽 자식에 대한 정보가 필요할 것이다.

이를 바탕으로 전위 , 후위 순회를 진행할 것이다.

그래서 본인은 ! 위와 같이 총 5개의 정보를 멤버변수로 갖는 구조체를 하나 만들어 주었다.

struct TREE { int Idx; int x; int y; TREE *Left; TREE *Right; };

#2. 입력 데이터 관리

입력 데이터로는 문제에서 주어진 Node들이 번호 순서대로 좌표로 주어지게 된다.

즉 ! 우리는 이 입력데이터만을 보고는 어떤 Node가 어떤 Node의 부모Node인지, 자식노드인지, 왼쪽자식인지, 오른쪽 자식인지 알 수가 없다. 따라서 이 입력 데이터를 알아볼 수 있게 정리하는 과정이 필요하다.

이를 위해서 본인은 #1에서 정의해놓은 구조체를 자료형으로 갖는 vector를 하나 선언해 주었다.

그리고, 이 입력데이터들을 vector에 삽입 후, vector를 정렬하는 방식으로 정리해 주었다.

즉 ! 다음과 같이 먼저, Vector에 입력 데이터들을 삽입해 주었다.

vector Tree; for (int i = 0; i < nodeinfo.size(); i++) { int x = nodeinfo[i][0]; int y = nodeinfo[i][1]; int Idx = i + 1; Tree.push_back({ Idx, x, y, NULL, NULL }); } 그리고 이 Vector를 정렬을 시켜 주었는데, 어떻게 정렬을 하면 좋을지 생각을 해보자. Tree에서 가장 중요한 것은, Root Node가 될 것이다. 그럼 Root Node는 어떤 특징을 가지고 있는지 알아보자. Root Node는 "주어진 Node들 중에서, y좌표 값이 가장 큰 Node" 가 된다. 즉 ! Node들끼리 비교를 해서 정렬을 할 때, 첫 번째 우선순위는, "y좌표값이 더 큰지 작은지" 가 될 것이다. 그 다음 우선순위는 어떻게 될까 ?? 바로 "x좌표"가 될 것이다. x좌표가 상대적으로 더 작다면, Left Child Node가 될 것이고 그게 아니라면 Right Child Node가 될 것이다. 이를 x좌표의 순서대로 정렬을 시켜 주었다. 즉 ! 위와 같은 그림이 주어졌을 때, Vector에 삽입 후 정렬을 시켰다면 Vector에는 다음과 같은 순서대로 Node들이 저장되어 있을 것이다. [ 7 , 4 , 2 , 6 , 1 , 3 , 9 , 8 , 5 ] 가장 Root Node부터 상대적으로 높이가 더 높은 Node들을 우선적으로, 그리고 같은 높이일 경우에는 x좌표가 더 작은 Node들 순으로 정렬을 시켜준 것이다. 이와 같이 정렬을 시켰다면 이제 우리는 이를 바탕으로 Tree를 만들 수 있다. #3. Tree만들기 이를 바탕으로 Tree를 본격적으로 만들어 보자. 역시나, 가장 기준이 되는 Node는 Root Node가 될 것이다. 그런데 ! Root Node는 어디에 저장되어 있을까 ?? 바로 #2에서 정렬시켜놓은 Vector의 0번 Index에 저장되어 있다. 우리는 이렇게 Root Node를 쉽게 찾을 수 있다. 이 Root Node를 기준으로 나머지 Node들의 위치를 파악해보자. #Case1 첫 번째 Case를 살펴보자. 빨강색 Node가 현재 기준이 되는 Node이고, 파랑색 Node가 현재 위치를 찾고자 하는 Node라고 생각해보자. 파랑색 Node가 빨강색 Node의 Left Child에 위치한다는 것을 눈으로 보고는 알 수 있지만, 이를 우리가 가진 정보로는 어떻게 파악할 수 있을까 ?? 바로 "x좌표"를 통해서 파악을 할 수가 있다. "빨강색 Node의 x좌표 > 파랑색 Node의 x좌표” 인 경우, 이 파랑색 Node는 빨강색 Node의 Left Child라고 판단할 수 있다.

그럼 ! 파랑색 Node를 삽입했다고 가정한 채로, 다음 Case로 넘어가보자.

#Case2

이 경우를 살펴보자. Case1에서 빨강색과 파랑색을 삽입을 한 후, 이어서 초록색 Node를 삽입하려고 한다.

그럼 ! 가장 먼저 Root Node인 빨강색 Node와 초록색 Node의 x좌표를 비교할 것이다.

당연히, 빨강색 Node의 x좌표가 초록색 Node의 x좌표보다 더 크기 때문에, 초록색 Node는 빨강색 Node의 Left Child에 속하는 Node라는 것을 알 수 있다. 그럼 Case1에서 진행한 것과 같이 그대로 빨강색 Node의 Left Child Node로 삽입을 해버리면 될까 ??? 눈으로 보고 있어서 알겠지만, 이는 잘못된 삽입이다. 왜냐하면 이미 파랑색 Node가 빨강색 Node의 Left Child에 자리잡고 있기 때문이다.

그럼 ! “빨강색 Node의 Left Child로 파랑색, 초록색 Node 2개가 올 수도 있지 않을까?” 라고 생각할 수 있지만, 그럴수가 없다. 왜냐하면 이 문제에서 주어진 트리는 “이진트리(Binary Tree)” 라고 했기 때문이다. “이진트리”는 자식이 딱 2개인 Tree를 의미한다. 즉 ! Node 하나 당 가질 수 있는 최대 자식의 수가 2개 이고, Left에 1개, Right에 1개를 가질 수 있는 Tree가 이진트리이기 때문에, 절대로 ! 초록색 Node가 파랑색 Node와 형제 Node같은 역할을 함과 동시에, 빨강색 Node의 Left Child로써의 역할을 수행할 수 없다는 것이다.

그럼 ! 이 경우에는 어떻게 해야 할까 ?? 이미 파랑색 Node가 Left Child로 자리잡고 있으면, 초록색 Node는 어떻게 될까 ??

기준점을 파랑색 Node로 바꿔주면 된다.

처음에는 빨강색 Node가 Root Node인지라 기준점으로 잡고, 빨강색 Node vs 초록색 Node로 비교를 했지만, 이 과정에서 파랑색 Node의 존재를 알게 되었으므로, 이제는 기준을 파랑색 Node로 잡아주면 된다.

파랑색 Node와 초록색 Node의 x좌표를 비교해보면, 파랑색 Node가 더 크고, 파랑색 Node의 Left Child Node가 비어있으므로 ! 초록색 Node의 자리는 파랑색 Node의 Left Child가 되는 것이다.

위의 Case1, 2에서 왼쪽 자식을 삽입하는 경우에 대해서 이야기를 했지만, 오른쪽 자식을 삽입할 때에도 똑같은 논리가 적용이 된다. 다를 것이 하나도 없다. 문제는 ! 이를 코드로 구현하는 것인데, 재귀를 이용하면 간단하게 구현할 수 있다.

재귀로 구현할 때 필요한 정보는 딱 2가지이다.

1. 기준이 되는 Node

2. 현재 자리를 찾는 Node

이 2가지 Node가 필요하니, 이 2개를 인자로 갖는 재귀함수를 구현하면 된다. 코드는 다음과 같다.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 void Make_Binary_Tree(TREE * Root, TREE * Child) { if (Root – > x > Child – > x) { if (Root – > Left = = NULL ) { Root – > Left = Child; return ; } Make_Binary_Tree(Root – > Left, Child); } else { if (Root – > Right = = NULL ) { Root – > Right = Child; return ; } Make_Binary_Tree(Root – > Right, Child); } } Colored by Color Scripter cs

line3 ~ 10)은 Left Child일 경우, 그 이후의 코드는 Right Child일 경우이다.

line3)에서 가장 Root Node의 x좌표와, 현재 삽입하려는 Node의 x좌표를 비교하고 있다.

line5)에서 아직 Left Node가 없는 경우 그대로 삽입을 하는 것을 볼 수 있다.

line10)은 “이미 Left Node가 있는 경우”를 표현한 것이다. 이 경우에는, Case2에서 기준 Node를 빨강색에서 파랑색 Node로 옮겼듯이, 기준이 되는 Node를 바꿔서 재귀를 호출하는 것을 확인할 수 있다.

이 이후의 코드는 Right Child일 경우 똑같이 적용되는 것을 구현한 것이다.

이로써 우리는 주어진 입력 데이터들을 하나의 Tree로 만드는 것을 완성했다.

이제 본격적으로 전위 , 후위 순회에 대해서 알아보자./

#4. 전위순회

먼저 간단하게 전위순회가 무엇인지에 대해서 부터 알아보고 가자.

전위순회는 Tree를 탐색하는 순서 중에 하나인데, 그 순서가 부모Node – Left Node – Right Node 순으로 탐색을 하게 된다.

위와 같은 Tree가 있을 때, 전위 순회는 다음과 같다.

[ 1 – 2 – 4 – 8 – 5 – 9 – 3 – 6 – 10 – 7 ]

이 순서에 대해서 이야기를 해보자면, 다음과 같다.

1. 가장 큰 부모 Node인 Root Node ‘1’번 Node를 탐색한다.

2. ‘1’의 Left Node인 ‘2’를 탐색한다.

3. 2의 과정에서 탐색한 ‘2’는 ‘1’의 Left Child인 동시에 또 다른 SubTree의 Root Node가 되기 때문에

여기서 ‘부모 – Left – Right’ 라는 전위순회 방식이 다시 적용된다.

4. 과정 3에 의해서 ‘2’의 Left Child인 ‘4’를 방문한다.

5. 과정 3과 같은 이유로 ‘4’는 또 다른 SubTree의 RootNode이므로 ‘부모 – Left – Right’ 방식이 다시 적용된다.

6. 과정 5에 의해서 ‘4’의 Left Child인 ‘8’을 방문한다.

7. ‘8’번 Node 이후에 또 다른 Node는 없으므로 이 Node의 부모 Node인 ‘4’로 가서 Right Child를 탐색해본다.

8. ‘4’의 Right Child는 없으므로 탐색을 중단하고 이 Node의 부모 Node인 ‘2’로 돌아가서 Right Child를 탐색해본다.

9. ‘2’의 Right Child인 ‘5’번 Node를 탐색한다.

10. 과정 3과 같은 이유로, ‘5’는 또 다른 Root Node이므로 ‘부모 – Left – Right’ 방식이 다시 적용된다.

11. ‘9’를 탐색 후, 더 이상의 탐색 Node가 없음을 확인하고 부모인 ‘5’, ‘5’의 부모인 ‘2’, ‘2’의 부모인 ‘1’까지 다시 돌아간다.

12. ‘1’의 Left Child를 모두 탐색했으므로 ‘1’의 Right Child를 탐색한다.

13. Right Child도 위와 같은 방식으로 탐색을 하면 3 – 6 – 10 – 7 이라는 순서로 탐색을 진행하게 된다.

이를 코드로 구현할 때에는 재귀를 사용하게 되는데 코드는 다음과 같다.

1 2 3 4 5 6 7 void PreOrder(TREE * Root, vector < int > & answer) { if (Root = = NULL ) return ; answer. push_back (Root – > Idx); PreOrder(Root – > Left, answer); PreOrder(Root – > Right, answer); } Colored by Color Scripter cs

매개변수로 호출되어 지고 있는 ‘Root’는 “현재 탐색하고 있는 Node”를 의미한다.

line4)에서 보면 “현재 Node를 탐색했습니다” 라고 표시해주기 위해서 answer에 삽입해 주는 과정이다.

line5)는 현재 Node를 탐색 후, Left Child를 탐색하기 위한 호출 과정이다.

line6)은 Left Child를 모두 탐색 후 , Right Child를 탐색하기 위한 호출 과정이다.

#5. 후위순회

후위순회 또한 Tree의 탐색하는 방법 중 하나이다. 그 순서가 Left – Right – 부모 순서로 탐색을 진행하게 된다.

위와 같은 Tree가 존재할 때 후위순회의 탐색 순서는 다음과 같다.

[ 8 – 4 – 9 – 5 – 2 – 10 – 6 – 7 – 3 – 1 ]

이 순서에 대해서 이야기를 해보자면 다음과 같다.

1. 가장 먼저, Left Child를 탐색하기 위해서 Root Node인 ‘1’의 Left Child인 ‘2’로 넘어간다.

2. ‘2’의 Left Child인 ‘4’, ‘4’의 Left Child인 ‘8’ 까지 넘어간다.

3. ‘8’의 Left Child는 존재하지 않으므로 ‘8’을 탐색한다.

4. 이 후, ‘8’이 후에는 더 이상의 Node가 존재하지 않으므로 이 Node의 부모 Node인 ‘4’의 Right Child를 찾아본다.

5. ‘4’의 Right Child는 없으므로 Right Child 다음 목표인 부모 노드인 ‘4’를 탐색한다.

6. ‘4’를 Root Node로 하는 Sub Tree를 모두 탐색하였으니, ‘4’의 부모 Node인 ‘2’의 Right Child를 탐색한다.

7. ‘2’의 Right Child인 ‘5’, ‘5’의 Right Child인 ‘9’를 탐색한다.

8. ‘9’ 이후에 또 다른 Node가 없으므로 ‘5’를 탐색한다.

9. ‘2’를 Root Node로 하는 Sub Tree의 Right Child를 모두 탐색하였으니, 이제 부모인 ‘2’를 탐색한다.

10. ‘1’을 Root Node로 하는 Tree의 Left Child를 모두 탐색하였으니, Right Child로 넘어간다.

11. 위와 같은 원리로 ‘1’의 Right Child를 후위순회로 탐색하면 10 – 6 – 7 – 3 – 1 이 된다.

이를 코드로 나타내면 다음과 같다.

1 2 3 4 5 6 7 void PostOrder(TREE * Root, vector < int > & answer) { if (Root = = NULL ) return ; PostOrder(Root – > Left, answer); PostOrder(Root – > Right, answer); answer. push_back (Root – > Idx); } Colored by Color Scripter cs

이와 같은 방식으로 이 문제를 해결할 수 있다.

[ 소스코드 ]

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 #include < string > #include < vector > #include < algorithm > using namespace std ; struct TREE { int Idx; int x; int y; TREE * Left; TREE * Right; }; bool Cmp(TREE A, TREE B) { if (A.y > = B.y) { if (A.y = = B.y) { if (A.x < B.x) { return true ; } return false ; } return true ; } return false ; } void Make_Binary_Tree(TREE * Root, TREE * Child) { if (Root - > x > Child – > x) { if (Root – > Left = = NULL ) { Root – > Left = Child; return ; } Make_Binary_Tree(Root – > Left, Child); } else { if (Root – > Right = = NULL ) { Root – > Right = Child; return ; } Make_Binary_Tree(Root – > Right, Child); } } void PreOrder(TREE * Root, vector < int > & answer) { if (Root = = NULL ) return ; answer. push_back (Root – > Idx); PreOrder(Root – > Left, answer); PreOrder(Root – > Right, answer); } void PostOrder(TREE * Root, vector < int > & answer) { if (Root = = NULL ) return ; PostOrder(Root – > Left, answer); PostOrder(Root – > Right, answer); answer. push_back (Root – > Idx); } vector < vector < int > > solution( vector < vector < int > > nodeinfo) { vector < vector < int > > answer; vector < TREE > Tree; for ( int i = 0 ; i < nodeinfo. size (); i + + ) { int x = nodeinfo[i][ 0 ]; int y = nodeinfo[i][ 1 ]; int Idx = i + 1 ; Tree. push_back ({ Idx, x, y, NULL , NULL }); } sort(Tree. begin (), Tree. end (), Cmp); TREE * Root = & Tree[ 0 ]; for ( int i = 1 ; i < Tree. size (); i + + ) Make_Binary_Tree(Root, & Tree[i]); vector < int > Pre_V; PreOrder(Root, Pre_V); vector < int > Post_V; PostOrder(Root, Post_V); answer. push_back (Pre_V); answer. push_back (Post_V); return answer; } Colored by Color Scripter cs

[프로그래머스] 길 찾기 게임(Python, Java)

반응형

https://programmers.co.kr/learn/courses/30/lessons/42892

길 찾기 게임

전무로 승진한 라이언은 기분이 너무 좋아 프렌즈를 이끌고 특별 휴가를 가기로 했다.

내친김에 여행 계획까지 구상하던 라이언은 재미있는 게임을 생각해냈고 역시 전무로 승진할만한 인재라고 스스로에게 감탄했다.

라이언이 구상한(그리고 아마도 라이언만 즐거울만한) 게임은, 카카오 프렌즈를 두 팀으로 나누고, 각 팀이 같은 곳을 다른 순서로 방문하도록 해서 먼저 순회를 마친 팀이 승리하는 것이다.

그냥 지도를 주고 게임을 시작하면 재미가 덜해지므로, 라이언은 방문할 곳의 2차원 좌표 값을 구하고 각 장소를 이진트리의 노드가 되도록 구성한 후, 순회 방법을 힌트로 주어 각 팀이 스스로 경로를 찾도록 할 계획이다.

라이언은 아래와 같은 특별한 규칙으로 트리 노드들을 구성한다.

트리를 구성하는 모든 노드의 x, y 좌표 값은 정수이다.

모든 노드는 서로 다른 x값을 가진다.

같은 레벨(level)에 있는 노드는 같은 y 좌표를 가진다.

자식 노드의 y 값은 항상 부모 노드보다 작다.

임의의 노드 V의 왼쪽 서브 트리(left subtree)에 있는 모든 노드의 x값은 V의 x값보다 작다.

임의의 노드 V의 오른쪽 서브 트리(right subtree)에 있는 모든 노드의 x값은 V의 x값보다 크다.

아래 예시를 확인해보자.

라이언의 규칙에 맞게 이진트리의 노드만 좌표 평면에 그리면 다음과 같다. (이진트리의 각 노드에는 1부터 N까지 순서대로 번호가 붙어있다.)

이제, 노드를 잇는 간선(edge)을 모두 그리면 아래와 같은 모양이 된다.

위 이진트리에서 전위 순회(preorder), 후위 순회(postorder)를 한 결과는 다음과 같고, 이것은 각 팀이 방문해야 할 순서를 의미한다.

전위 순회 : 7, 4, 6, 9, 1, 8, 5, 2, 3

후위 순회 : 9, 6, 5, 8, 1, 4, 3, 2, 7

다행히 두 팀 모두 머리를 모아 분석한 끝에 라이언의 의도를 간신히 알아차렸다.

그러나 여전히 문제는 남아있다. 노드의 수가 예시처럼 적다면 쉽게 해결할 수 있겠지만, 예상대로 라이언은 그렇게 할 생각이 전혀 없었다.

이제 당신이 나설 때가 되었다.

곤경에 빠진 카카오 프렌즈를 위해 이진트리를 구성하는 노드들의 좌표가 담긴 배열 nodeinfo가 매개변수로 주어질 때,

노드들로 구성된 이진트리를 전위 순회, 후위 순회한 결과를 2차원 배열에 순서대로 담아 return 하도록 solution 함수를 완성하자.

제한사항

nodeinfo는 이진트리를 구성하는 각 노드의 좌표가 1번 노드부터 순서대로 들어있는 2차원 배열이다. nodeinfo의 길이는 1 이상 10,000 이하이다. nodeinfo[i] 는 i + 1번 노드의 좌표이며, [x축 좌표, y축 좌표] 순으로 들어있다. 모든 노드의 좌표 값은 0 이상 100,000 이하인 정수이다. 트리의 깊이가 1,000 이하인 경우만 입력으로 주어진다. 모든 노드의 좌표는 문제에 주어진 규칙을 따르며, 잘못된 노드 위치가 주어지는 경우는 없다.

입출력 예

nodeinfo result [[5,3],[11,5],[13,3],[3,5],[6,1],[1,3],[8,6],[7,2],[2,2]] [[7,4,6,9,1,8,5,2,3],[9,6,5,8,1,4,3,2,7]]

입출력 예 설명

입출력 예 #1

문제에 주어진 예시와 같다.

풀이 설명

1. nodeinfo의 각 원소(x,y위치)에 노드번호(인덱스+1)를 추가한다.

(Java의 경우, Node 클래스를 만들어 필드로 x위치, y위치, 노드번호를 갖도록 한다.

이 Node를 저장하는 ArrayList를 생성한다.)

2. nodeinfo를 x를 기준으로 오름차순 정렬한 arrX, y를 기준으로 내림차순 정렬한 arrY를 생성한다.

3. 전위순회하는 함수 preorder, 후위순회하는 함수 postorder를 정의한다.

4. preorder의 매개변수로 arrX, arrY, 답을 저장할 배열 answer을 받는다.

5. 중심이 될 노드 node=arrY[0]을 선언한다. (y축값이 제일 높은 노드가 루트이므로)

중심 노드의 arrX에서의 인덱스를 알아낸다. (idx)

중심 노드를 기준으로 왼쪽 노드들을 저장할 arrY1, 오른쪽 노드들을 저장할 arrY2를 준비한다.

6. arrY에서 중심노드를 제외한 인덱스 1~마지막까지 탐색한다.(i)

6-1. arrY[i]의 x값이 중심노드의 x값보다 작다면 arrY1에 삽입, 크다면 arrY2에 삽입한다.

7. 답을 저장하는 answer에 중심노드의 번호인 node[2]를 삽입한다.

8. 만약 arrY1의 크기가 0이 아니라면 arrY1과 arrX의 0부터 idx까지로 다시 preorder를 재귀호출한다.

9. 만약 arrY2의 크기가 0이 아니라면 arrY2와 arrX의 idx+1부터 끝까지로 다시 preorder를 재귀호출한다.

10. 후위순회 postorder도 똑같지만 7,8,9번의 순서를 후위순회 순서인 8,9,7로 바꾼다.

Python3 코드

import sys sys.setrecursionlimit(10**6) def preorder(arrY, arrX, answer): node = arrY[0] idx = arrX.index(node) arrY1 = [] arrY2 = [] for i in range(1, len(arrY)): if node[0] > arrY[i][0]: arrY1.append(arrY[i]) else: arrY2.append(arrY[i]) answer.append(node[2]) if len(arrY1) > 0: preorder(arrY1, arrX[:idx], answer) if len(arrY2) > 0: preorder(arrY2, arrX[idx + 1:], answer) return def postorder(arrY, arrX, answer): node = arrY[0] idx = arrX.index(node) arrY1 = [] arrY2 = [] for i in range(1, len(arrY)): if node[0] > arrY[i][0]: arrY1.append(arrY[i]) else: arrY2.append(arrY[i]) if len(arrY1) > 0: postorder(arrY1, arrX[:idx], answer) if len(arrY2) > 0: postorder(arrY2, arrX[idx + 1:], answer) answer.append(node[2]) return def solution(nodeinfo): preanswer = [] postanswer = [] for i in range(len(nodeinfo)): nodeinfo[i].append(i+1) arrY = sorted(nodeinfo, key = lambda x : (-x[1], x[0])) arrX = sorted(nodeinfo) preorder(arrY, arrX, preanswer) postorder(arrY, arrX, postanswer) return [preanswer, postanswer]

Java 코드

import java.util.*; public class Node{ private int x; private int y; private int idx; public Node(int x, int y, int idx) { this.x = x; this.y = y; this.idx = idx; } public int getX(){ return x; } public int getY(){ return y; } public int getIdx(){ return idx; } @Override public String toString(){ return “[” + x + ” ,” + y + ” ,” + idx + “]”; } } class Solution { public void sortX(List list){ Collections.sort(list, new Comparator(){ @Override public int compare(Node o1, Node o2){ if(o1.getX() > o2.getX()){ return 1; } else{ return -1; } } }); } public void sortY(List list){ Collections.sort(list, new Comparator(){ @Override public int compare(Node o1, Node o2){ if(o1.getY() > o2.getY()){ return -1; } else if(o1.getY() == o2.getY()){ if(o1.getX() > o2.getX()) return 1; else return -1; } else return 1; } }); } public List preOrder(List arr, List arrX, List arrY){ Node node = arrY.get(0); int index = arrX.indexOf(node); List arrY2 = new ArrayList<>(); List arrY3 = new ArrayList<>(); for(int i=1; i 0) preOrder(arr, arrX.subList(0, index), arrY2); if(arrY3.size() > 0) preOrder(arr, arrX.subList(index + 1, arrX.size()), arrY3); return arr; } public List postOrder(List arr, List arrX, List arrY){ Node node = arrY.get(0); int index = arrX.indexOf(node); List arrY2 = new ArrayList<>(); List arrY3 = new ArrayList<>(); for(int i=1; i 0) postOrder(arr, arrX.subList(0, index), arrY2); if(arrY3.size() > 0) postOrder(arr, arrX.subList(index + 1, arrX.size()), arrY3); arr.add(node.getIdx()); return arr; } public int[][] solution(int[][] nodeinfo) { int len = nodeinfo.length; int[][] answer = new int[2][len]; List preList = new ArrayList<>(); //전위순회 순서저장 List postList = new ArrayList<>(); //후위순회 순서저장 List nodeinfo2 = new ArrayList(); //nodeinfo원소에 인덱스까지 더한 원소 저장 List arrX = new ArrayList(); //nodeinfo2를 x정렬 List arrY = new ArrayList(); //nodeinfo2를 (-y, x)정렬 for(int i=0; i

길 찾기 게임

728×90

300×250

SMALL

문제

https://programmers.co.kr/learn/courses/30/lessons/42892

나의 풀이

preorder와 postorder로 트리를 순회하는 것은 쉽다.(모르면 검색을 해보면 금방 나올 것이다.) 이 문제의 핵심은 주어진 정보로 트리를 얼마나 잘 구현하는가이다.

nodeinfo를 y좌표에 대해 내림차순, x좌표에 대해 오름차순으로 정렬한다. 정렬된 nodeinfo를 순회하며 각 노드의 자리를 찾아 삽입한다.

문제에서 주어진 조건 중 왼쪽 서브트리의 모든 노드들의 x좌표는 부모 노드의 x좌표보다 작고, 오른쪽 서브트리는 크다는 조건을 사용한다. root부터 시작해 아래로 내려가면서 위의 조건을 사용해 자리를 찾아간다.

코드

import sys sys.setrecursionlimit(10**6) pre, post = [], [] class Tree: def __init__(self, nodeid, data, left=None, right=None): self.id = nodeid self.data = data self.left = left self.right = right def preorder(root): if not root: return pre.append(root.id) if root.left: preorder(root.left) if root.right: preorder(root.right) def postorder(root): if not root: return if root.left: postorder(root.left) if root.right: postorder(root.right) post.append(root.id) def solution(nodeinfo): answer = [] sorted_nodeinfo = sorted(nodeinfo, key = lambda x : (-x[1],x[0])) # tree 구성하기 root = None for node in sorted_nodeinfo: if not root: root = Tree(nodeinfo.index(node)+1,node) else: cur = root while True: if node[0] < cur.data[0]: if not cur.left: cur.left = Tree(nodeinfo.index(node)+1,node) break else: cur = cur.left continue elif node[0] > cur.data[0]: if not cur.right: cur.right = Tree(nodeinfo.index(node)+1,node) break else: cur = cur.right continue preorder(root) postorder(root) return [pre, post]

728×90

300×250

LIST

[프로그래머스]길 찾기 게임 – JAVA

[프로그래머스]길 찾기 게임

programmers.co.kr/learn/courses/30/lessons/42892

풀이

입력받은 데이터를 가지고 트리를 만들고, 전위순회/후위순회한 결과를 반환하면 된다. 트리에 대해 잘 알고 있었다면 크게 어려움 없이 풀 수 있는 문제였고 트리에 대해 잘 모르더라도 이 문제를 통해 트리를 이해하는데 도움이 될만한 좋은 문제라고 생각한다.

이 문제에서 요구되는 트리를 x값을 기준으로 생각한다면 이진검색트리라고 볼 수도 있을 것 같당.

트리들은 서로 연결되어 있어야 하므로 Node클래스를 만들어 x값, y값, value, 왼쪽 자식, 오른쪽 자식을 저장하도록 만들어 주었다.

입력받은 노드 정보를 문제의 조건에 맞는 트리 구조로 만들기 위해 정렬해 주었다. 이때 y값은 더 큰 값이 먼저 오도록, y값이 같다면 x값이 더 작은 값이 먼저 오도록 정렬해 주었다.

다음으로 정렬 후 0번 인덱스 값을 root로 지정하고 root를 기준으로 노드들을 insert해주었다. root보다 x값이 더 작다면 왼쪽으로, 더 크다면 오른쪽으로 insert해주었다. 이때 이미 왼쪽, 오른쪽 자식이 존재하면 자식의 값과 순환적으로 비교하여 적절한 위치를 찾아 주었다.

트리를 완성했다면 이제 순회만 해주면된다. 순회는 워낙 정형적인 알고리즘이라 어려울 것이 없었다.

코드

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 import java.util. * ; class Solution { int [][] result; int idx; public int [][] solution( int [][] nodeinfo) { //노드를 입력받는다. Node[] node = new Node[nodeinfo. length ]; for ( int i = 0 ; i < nodeinfo. length ; i + + ) { node[i] = new Node(nodeinfo[i][ 0 ], nodeinfo[i][ 1 ], i + 1 , null , null ); } //y값 큰 순서대로, y값 같다면 x값 작은 순서대로 정렬 Arrays.sort(node, new Comparator < Node > () { @Override public int compare(Node n1, Node n2) { if (n1.y = = n2.y) return n1.x – n2.x; else return n2.y – n1.y; } }); //트리를 만든다. Node root = node[ 0 ]; for ( int i = 1 ; i < node. length ; i + + ) { insertNode(root, node[i]); } result = new int [ 2 ][nodeinfo. length ]; idx = 0 ; preorder(root); //전위 순회 idx = 0 ; postorder(root); //후위 순회 return result; } public void insertNode(Node parent, Node child) { if (parent.x > child.x) { if (parent.left = = null ) parent.left = child; else insertNode(parent.left, child); } else { if (parent.right = = null ) parent.right = child; else insertNode(parent.right, child); } } public void preorder(Node root) { if (root ! = null ) { result[ 0 ][idx + + ] = root.value; preorder(root.left); preorder(root.right); } } public void postorder(Node root) { if (root ! = null ) { postorder(root.left); postorder(root.right); result[ 1 ][idx + + ] = root.value; } } public class Node { int x; int y; int value; Node left; Node right; public Node( int x, int y, int value, Node left, Node right) { this .x = x; this .y = y; this .value = value; this .left = left; this .right = right; } } } Colored by Color Scripter cs

Computer Science & Engineering

https://programmers.co.kr/learn/courses/30/lessons/42892

문제 설명

이 문제는 좌표로 주어지는 노드들을 트리로 이진 트리로 만들어 전위 순회, 후위 순회 결과를 리턴하는 문제이다. 예시는 다음과 같다.

문제 예시

첫 번째 그림과 같이 주어진 좌표를 아래의 그림처럼 이진 트리 구조로 만드는 것이다. 트리를 구성하는 노드들의 규칙은 다음과 같다.

트리를 구성하는 모든 노드의 x, y 좌표 값은 정수이다. 모든 노드는 서로 다른 x값을 가진다. 같은 레벨(level)에 있는 노드는 같은 y 좌표를 가진다. 자식 노드의 y 값은 항상 부모 노드보다 작다. 임의의 노드 V의 왼쪽 서브 트리(left subtree)에 있는 모든 노드의 x값은 V의 x값보다 작다. 임의의 노드 V의 오른쪽 서브 트리(right subtree)에 있는 모든 노드의 x값은 V의 x값보다 크다.

위 예시의 전위 순회와 후위 순회의 결과는 다음과 같이 나온다.

전위 순회 : 7, 4, 6, 9, 1, 8, 5, 2, 3

후위 순회 : 9, 6, 5, 8, 1, 4, 3, 2, 7

풀이

이 문제를 풀기 위해서 우선 트리를 구현해야한다. 연결리스트를 이용하여 구현하면 복잡해진다고 판단하여 배열을 이용하였다.

1. 트리의 표현

pair로 구성된 배열을 이용하여 first에는 왼쪽 자식, second에는 오른쪽 자식의 번호를 저장하였다. 트리를 사용하기 위해서는 트리를 초기화해야한다. 자식을 가리키는 인덱스 번호가 자기 자신과 같다면 리프노드로 판단하도록 초기화하였다.

2. 노드 순서

입력으로 주어진 노드 정보들을 루트 노드부터 순서대로 정렬해야한다. 이때 주어진 배열의 (인덱스 번호 + 1)이 노드의 번호이기 때문에 주어진 배열 자체를 정렬시키면 안되고 인덱스 번호와 좌표를 유지해야한다. 따라서 각 노드의 번호를 통해 좌표를 쉽게 찾기 위해 map을 사용하였고 전위 순회 방식으로 노드를 정렬하기 위해 정렬을 위한 node라는 배열을 따로 선언하였다.

3. 트리 구현

그 다음에는 정렬된 노드를 순서대로 트리에 붙여나가야한다. 트리를 만드는 find함수를 따로 구현하였다. find 함수는 다음과 같이 동작한다.

현재 노드의 x좌표보다 추가하는 노드의 x좌표가 작은 경우(왼쪽 자식인 경우) 만약 왼쪽 자식이 자기 자신일 때(리프노드일 때) 왼쪽 자식에 붙인다.

그렇지 않으면 재귀적으로 왼쪽 자식과 현재 노드를 방금 과정과 똑같이 비교한다. 현재 노드의 x좌표보다 추가하는 노드의 x좌표가 큰 경우(오른쪽 자식인 경우) 만약 오른쪽 자식이 자기 자신일 때(리프노드일 때) 오른쪽 자식에 붙인다.

그렇지 않으면 재귀적으로 오른쪽 자식과 현재 노드를 방금 과정과 똑같이 비교한다.

4. 전위 순회와 후위 순회

전위 순회는 왼쪽 오른쪽 자식을 탐색하기 전에 자기 자신을 경로에 넣으면 된다. 반대로 후위 순회는 왼쪽 오른쪽 자식을 탐색하고 난 이후에 자기 자신을 경로에 넣으면 된다.

소스코드

#include #include #include #include

#include using namespace std; pair tree[10001]; map> m; vector frontpath; //전위순회 경로 vector endpath; //후위순회 경로 struct edge { //정렬을 위한 구조체 int idx, x, y; }; bool cmp(edge a, edge b) { //루트노드부터 순서대로 정렬하는 비교함수 if(a.y == b.y) { return a.x < b.x; } else return a.y > b.y; } void find(int now, edge e) { //적절한 위치 찾기 pair nowpos = m[now]; if(nowpos.first > e.x) { //왼쪽자식인 경우 if(tree[now].first == now) { //왼쪽 자식 끝인 경우 tree[now].first = e.idx; //왼쪽 자식에 붙이기 return; } else { //끝이 아닌 경우 find(tree[now].first, e); //재귀적으로 탐색 } } else { //오른쪽 자식인 경우 if(tree[now].second == now) { //오른쪽 자식 끝인 경우 tree[now].second = e.idx; return; } else { find(tree[now].second, e); } } return; } void front(int now) { //전위순회 frontpath.push_back(now); //경로 먼저 추가 if(tree[now].first != now) { //리프노드가 아니라면 front(tree[now].first); //왼쪽 자식 탐색 } if(tree[now].second != now) {//리프노드가 아니라면 front(tree[now].second); //오른쪽 자식 탐색 } } void end(int now) { //후위순회 if(tree[now].first != now) { //리프노드가 아니라면 end(tree[now].first); //왼쪽 자식 탐색 } if(tree[now].second != now) { //리프노드가 아니라면 end(tree[now].second); //오른쪽 자식 탐색 } endpath.push_back(now); //경로 나중에 추가 } vector> solution(vector> nodeinfo) { vector> answer; vector node; //정렬을 위한 배열 for(int i = 1; i <= nodeinfo.size(); i++) { //트리 초기화 tree[i].first = i; //왼쪽 자식을 자기 자신으로 tree[i].second = i; //오른쪽 자식을 자기 자신으로 } for(int i = 0;i < nodeinfo.size(); i++) { node.push_back({i+1, nodeinfo[i][0], nodeinfo[i][1]}); //정렬을 위한 배열 m[i+1] = {nodeinfo[i][0], nodeinfo[i][1]}; //각 노드 번호별 x, y좌표 map에 저장 } sort(node.begin(), node.end(), cmp); //y좌표가 큰순, x좌표가 작은순으로 정렬 int root = node[0].idx; //루트 인덱스 번호 for(int i = 1; i < node.size(); i++) { edge now = node[i]; //현재 노드 find(root, now); //자식으로 붙이기 } front(root); //전위순회 end(root); //후위순회 answer.push_back(frontpath); answer.push_back(endpath); return answer; } 결과

키워드에 대한 정보 길 찾기 게임

다음은 Bing에서 길 찾기 게임 주제에 대한 검색 결과입니다. 필요한 경우 더 읽을 수 있습니다.

이 기사는 인터넷의 다양한 출처에서 편집되었습니다. 이 기사가 유용했기를 바랍니다. 이 기사가 유용하다고 생각되면 공유하십시오. 매우 감사합니다!

사람들이 주제에 대해 자주 검색하는 키워드 [썩쏘TV]신박한 길찾기 게임 GROW MAZE

  • 아프리카티비
  • 썩쏘TV
  • 플래시게임
  • 공략
  • 게임
  • 중독성게임
  • 어려운게임
  • 공갈 썩쏘
  • 멘붕게임
  • 썩컨
  • 아프리카비제이
  • 아프리카
  • 실황
  • 게임실황
  • 신박한게임
  • 길찾기게임
  • 썩쏘
  • 공갈 썩소
  • 썩소
  • grow maze
[썩쏘TV]신박한 #길찾기 #게임 #GROW #MAZE


YouTube에서 길 찾기 게임 주제의 다른 동영상 보기

주제에 대한 기사를 시청해 주셔서 감사합니다 [썩쏘TV]신박한 길찾기 게임 GROW MAZE | 길 찾기 게임, 이 기사가 유용하다고 생각되면 공유하십시오, 매우 감사합니다.

See also  기상 직 기출 | 기상직 공무원 기상학개론 20.07.11 시행 기상직 기출해설특강 최근 답변 101개

Leave a Reply

Your email address will not be published. Required fields are marked *