-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
30-9kyo-hwang #115
30-9kyo-hwang #115
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
예제 보고 이해하는 것도 바로바로 안되는데 코드로 구현까지 하시는 거 진짜 엄청난 것 같아요... 수고하셨습니다😊
뭐얔ㅌㅋㅌㅋㅌ 그림보고 한참 웃었어요ㅋㅌㅋㅌㅋㅌ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
엄청 어려운 문제인 것 같은데 자세하게 설명해주셔서 이해하면서 볼 수 있었습니다!
중간에 있는 그림도 너무 웃겼네요ㅋㅋㅋㅋㅋㅋㅋㅋㅋ😁
엣지 케이스라는 것도 있군요?
찾아보니 극한의 상황에서 왜곡되는 현상이라고 하는데 알고리즘 쉽지 않네요...🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
꼬리잡기를 사용해야 하고, 제일 끝에 있는 사람을 우선적으로 선택하는 것이 최소로 버튼을 누르는 방법이겠구나! 는 금방 알아챘는데... 이걸 어떻게 구현해야하지?에서 2일을 태웠습니다. 유니온 파인드인가..? 네... 하루를 날렸구요. 그냥 그래프로 해볼까 하다가 그래프로도 이래저래 하다가 결국엔 포기했습니다. 😢
설명보고나서야 저런 방법이라는 생각이 드네요...
엣지 케이스에 대해서 생각해봤는데...
3층 사람이 5층을 가고싶고, 5층 사람이 3층에 가고 싶은 사람이 있다면, 나갈 사람만 있는 층이 아니니까... 독립된 사이클이면 탐색이 안되지 않을까?! 라는 추측만 하고 있습니다...
리뷰 늦어서 죄송합니다😭 다음 PR 리뷰도 이어서 호다닥 하겠습니당...
🔗 문제 링크
23296 엘리베이터 조작
✔️ 소요된 시간
약 3시간
✨ 수도 코드
1. 문제
1명만 태울 수 있는 엘리베이터가 있다. 이 엘리베이터는 관리실에서만 조작 가능하며, 1층에서 출발한다.
![image](https://private-user-images.githubusercontent.com/49135176/307820381-3458d220-5c8b-4742-b6f1-eefda3246464.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk1MDIxODMsIm5iZiI6MTczOTUwMTg4MywicGF0aCI6Ii80OTEzNTE3Ni8zMDc4MjAzODEtMzQ1OGQyMjAtNWM4Yi00NzQyLWI2ZjEtZWVmZGEzMjQ2NDY0LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTQlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjE0VDAyNTgwM1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTg4MjNlYWRjM2I2YTM4Zjc2Y2ExNmZmNzczOTM5ZDNhZGM2YmE2NWEyYTM0MjhiMTQ5ZDExYTMxYTRiM2U1NmEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.7_6Gci0iF0VsTmELarU3L-KfhO7X9m2DafI8VTcKh6A)
위와 같이 한 층 당 한 명씩 기다리고 있을 때, 사람들을 모두 원하는 층에 내려주기 위해 버튼을 눌러야 하는 최소 횟수와 눌러야하는 버튼 순서를 출력하라.
2. 들어가기에 앞서
알고리드미 디코 지박령 @pknujsp @tgyuuAn 이 막 얘기하고 있길래 뭔가 하고 봤는데�
![image](https://private-user-images.githubusercontent.com/49135176/307826179-c00a79e4-723d-46d6-9019-e040e0cc16f7.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk1MDIxODMsIm5iZiI6MTczOTUwMTg4MywicGF0aCI6Ii80OTEzNTE3Ni8zMDc4MjYxNzktYzAwYTc5ZTQtNzIzZC00NmQ2LTkwMTktZTA0MGUwY2MxNmY3LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTQlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjE0VDAyNTgwM1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWZhZDgyYzZlY2EwMzcyNzA0NjU3ODAwNGY0OWQyYWZlZDJiYjA2MWJmYjY3ODdmZTZkZjdhOGRhZjYwMzMwZTUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.j74uPmC5SM9rcBeUpB3JO-NKkNulJuSa4vKrmcXqZzs)
�나도 당해버렸다.
위상정렬 문제라길래 그거를 고려해서 코드를 막 짰었는데, 솔직히 위상정렬 아닌 것 같다. 사실상 그리디 문제라고 생각된다.
3. 풀이
원하는 층에 내려주기 위해 눌러야 하는 버튼 횟수를 최소로 만드는 것이 목적이다. 위의 예시를 다시 한 번 확인해보자.
1층 사람은 4층, 2층 사람은 4층, 3층 사람은 1층, 4층 사람은 5층, 5층 사람은 2층을 가야 한다.
만약 1층부터 각 사람마다 원하는 층을 바로바로 데려다 준다고 하면, 버튼은 4 - 2 - 4 - 3 - 1 - 4 - 5 - 2 이렇게 눌러져야 할 것이다.
반면 사람을 내리자마자 그 층의 사람을 다시 태워 바로 보내버리는, 줄줄이 이어서 태우고 내리고 태우고 내리고를 반복한다고 해보자. 아래와 같은 순서라면 4 - 5 - 2 - 4 - 3 - 1이다.
버튼을 눌러야 하는 횟수가 6번으로 줄어든다. 이런 식으로 줄줄이 물어서 옮기는 것이 버튼을 누르는 횟수를 줄일 수 있다. 이를 코드로 구현해보자.
엘리베이터 이동을 담당하는 함수이다. IsOutOfHere[Floor]는 "Floor층에 있는 사람이 나갔는가"를 의미한다. 각 층에는 한 사람이 존재하므로, 한 번 true로 바뀌면 더 이상 Floor 층에서 다른 층으로 이동할 수 없기 때문에 이런 조건이 걸려있다.
나갈 사람이 있다면 반복문 안에 들어오면서, true 처리를 해주고 다음 층 A[Floor]를 판단한다.
NumOfComeHere[NextFloor]는 NextFloor 층에 가고자 하는 사람 수를 의미한다. 만약 이 수가 0이라면 Floor 층의 사람도 이미 이전 엘리베이터 이동에 의해 갔음을 의미하므로 다음 층으로 이동하지 않아야 한다.
다음 층으로 가지 않았다면 문제에서 찾고자 하는 버튼이므로 기록하고, 현재 층을 다음 층으로 갱신해준다.
최초의 엘리베이터는 1층에 있으므로, 1층에서 시작하는 함수를 한 번 호출한다.
예시를 그래프로 표현해서 1층에 대해 Elevation 함수를 수행하면 다음과 같이 진행된다.
![제목을-입력해주세요_ (1)](https://private-user-images.githubusercontent.com/49135176/307840649-e3a2544c-18c7-4419-84b2-22358f199b05.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk1MDIxODMsIm5iZiI6MTczOTUwMTg4MywicGF0aCI6Ii80OTEzNTE3Ni8zMDc4NDA2NDktZTNhMjU0NGMtMThjNy00NDE5LTg0YjItMjIzNThmMTk5YjA1LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTQlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjE0VDAyNTgwM1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTZkMjNlMjYxZjgwNjk1MzQ4YzRjODgwODQ2NTQzMDlmMTY1NjQwNWM5ZmEwZmY4MmViODdkYmIxNzhjMjM2ODAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.RC0NDrn0fsy1ySx9Qj8Ep1V3oB2QasCSSeAJOtJ0Yzg)
1층에서 한 사이클을 수행하고 나면, 위 그림처럼 꼬리물기에 포함되지 않은 층이 있을 수 있다. 이런 층들은 1. 나갈 사람만 있던가 2. 나갈 사람도 있고 들어와야 할 사람도 있거나 3. 들어와야 할 사람만 있거나 셋 중 하나일 것이다.
위 설명에서 짐작챘을 것인데, 결국 같은 원리로 나갈 사람만 있는 층으로 이동해서 꼬리물기를 시전해버리는 게 버튼 누르는 횟수가 최소가 된다.
그래서 모든 층을 쭉 훑어보면서, Floor 층에서 안나간 사람이 있으며 더 이상 Floor 층에 들어올 사람이 없는 층을 우선적으로 Elevation 함수를 수행한다.
여기서는 1층에서 출발하는 것이 아니기 때문에, 지금 Floor로 이동을 해와야 해서 Floor 층도 기록을 해줘야 한다.
이 부분은 약간 의문인게, 이렇게 순회를 하고도 아직 방문하지 않은 층이 남아있을 수 있다고 한다. �엣지 케이스를 찾아보고 싶은데, 떠오르지가 않는다.
암튼 아직 순회하지 않은 케이스를 처리하기 위해 한 번 더 순회한다.
마지막으로 누른 버튼 횟수와 버튼 종류를 출력하면 완성이다.
전체 코드
📚 새롭게 알게된 내용
왜 위상정렬 카테고리가 붙었는 지 모르겠다. 진입차수 개념이 사용돼서 그런가?
그리고 마지막에 한 번 더 모든 층을 확인해야 하는 이유가 무엇인 지 명확히 모르겠다. 엣지 케이스 하나만 잡아서 설명해주실 분...?