Skip to content

[김유성-13주차 알고리즘 스터디] #65

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

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

Rayd-kim
Copy link

🚀 싸피 15반 알고리즘 스터디 13주차 [김유성]

📌 문제 풀이 개요

  • 이번 PR에서는 다음 5문제의 풀이를 포함합니다.
  • 각 문제에 대한 풀이 과정과 접근 방식을 설명합니다.

✅ 문제 해결 여부

  • 마법사 상어와 복제
  • 궁금한 민호
  • 놀이 공원
  • BFS 스페셜 저지
  • 청소년 상어

💡 풀이 방법

문제 1: 마법사 상어와 복제

문제 난이도
골드 1

문제 유형
구현, 시뮬레이션

접근 방식 및 풀이

  1. 문제에 맞게 solve() 함수 안에서 실행 될 순서를 정했습니다.
    복제 마법 실행 -> 물고기 이동 -> 상어 이동 방향 구하기 -> 잡아먹기 -> 기존의 물고기 냄새 지우기 -> 복제
    이 순서로 진행을 하였습니다.
  2. Fish 객체를 만들고, 이를 담는List list와 Fish[][] map을 만들었습니다. 이 때 fish를 map에 바로 저장하는 것이 아니라 list에 저장해주었습니다. map에 2차원 배열 형태로 저장하면, 물고기를 이동시킬 때 이동 한 물고기인지 아닌지 구분이 어렵기 때문에 이렇게 구현하였습니다.
  3. 물고기를 이동할 때 기존 방향 + 반시계 방향으로 회전하면서 체크를 해주었고 만약 이동 가능하면 바로 for문을 1개만 빠져나오도록 했습니다. (이 때, GoTo문 비슷한 기능을 사용했습니다. -> 준영님이 이런식으로 2, 3중 for문에서 원하는 단계까지만 빠져나오게 자주사용하셔서 한번 써먹어 봤습니다.) 그리고 map을 초기화 시켜서 여기에 물고기를 넣어줍니다.
  4. dfs를 이용해서 상어의 이동위치를 구합니다.
  5. dfs를 이용해서 구한 상어의 이동대로 상어를 이동시키면서 물고기를 잡아먹습니다. 이 때, 사전순으로 방향을 구하기 때문에 이것을 div하면서 사용했습니다.
  6. map에 있는 물고기를 다시 List에다가 넣어주었습니다.
  7. smell 이라는 2차원 배열에 물고기의 냄새를 저장하는데 이 값이 0보다 크면 1씩 줄여주었습니다.
  8. 복제list에 있는 물고기를 기존의 물고기 List에 넣어주었습니다.

문제 2: 궁금한 민호

문제 난이도
골드 2

문제 유형
플로이드-워셜, 최단 경로

접근 방식 및 풀이
처음에 불가능한 경우가 잘 이해가 가지 않았습니다. 문제를 살펴보니까 최단경로를 구했다고 하였는데 이 말은 플로이드-워샬을 이용해서 i -> j까지 가는 경로를 구한 것이라고 생각했습니다. 즉, i -> j로 이어지는 직선 간선의 값이 무조건 최소이다. 만약 이 값이 최소가 아니면 불가능한 경우다. 로 이해했습니다.

이를 바탕으로 해서 풀이법을 고민하다가 간선을 하나씩 지워가는 식으로 문제를 풀었습니다.

  1. 불가능한 경우인지 플로이드-워샬을 사용해서 체크합니다. 만약 불가능하면 바로 -1을 출력합니다.
  2. 조합을 이용해서 간선을 하나씩 지워봅니다. 지우고나서 다익스트라를 통해서 최단경로를 구합니다. 만약 a->b로 향하는 간선을 지우고 다익스트라를 돌렸을 때, 같은 가중치를 가지는 최단경로가 있다면 (즉, a->b까지의 직선 간선을 지웠을 때 a -> k, k -> b 를 통해서 이동하는 가중치가 최단과 같다면) 그 간선을 지워도 된다고 생각해서 지워나갔습니다.
  3. 간선을 지울 때, 맨 처음에 전체 간선의 가중치를 전부 더해준 변수(ret)에서 지우는 간선의 가중치 만큼의 값을 빼주었습니다.
  4. 모든 경로를 확인한 후 ret을 출력해줍니다.

문제 3: 놀이 공원

문제 난이도
골드 1

문제 유형
이분 탐색, 매개 변수 탐색

접근 방식 및 풀이
시간을 매개변수로 해서 이분 탐색을 진행했습니다. 해당 시간까지 각 놀이기구당 태울 수 있는 아이의 수를 합했을 때 N보다 큰지 작은지를 기준으로 했습니다. 이 때, 딱 나누어 떨어지지 않더라도 그 시간에 해당 놀이기구에 탑승하고 있는 아이가 있을 수 있기 때문에 이를 같이 고려해주어야 합니다.
이를 이용해서 아이의 수를 전체 놀이기구를 1싸이클 정도 돌았을 때 처리할 수 있을 정도로 낮춰주었습니다.
그리고 우선순위 큐를 이용해서 놀이기구에 1명씩 태워가면서 N이 0일 때 값을 출력해주도록 했습니다.


문제 4: BFS 스페셜 저지

문제 난이도
골드 3

문제 유형
BFS, 그래프 탐색

접근 방식 및 풀이
나와야 하는 숫자의 순서를 Queue에다가 저장해주었습니다.
그리고 옳은 값인지 확인해주기 위해서 Queue를 만들었고, 여기다가 Set을 저장해주었습니다.
이렇게 한 이유는 BFS는 들어간 단계(넓이)순서로 나와야 하면서 Queue에 들어간 자식들이 순서 상관없이 나와도 되기 때문입니다.
그래서 input값을 하나씩 확인하면서 만약 set안에 있다면 그대로 진행하고 없다면 잘못된 것이므로 바로 false를 return하도록 구현했습니다.


문제 5: 청소년 상어

문제 난이도
골드 1

문제 유형
구현, 시뮬레이션, 백트래킹

접근 방식 및 풀이
Fish객체를 만들고 Fish[][] map이라는 2차원 배열로 물고기를 저장해주었습니다.
이 문제의 핵심은 상어가 최대로 잡아먹는 물고기 번호의 합을 구하는 것이기 때문에 dfs를 이용했습니다.

  1. dfs함수의 인자로 상어의 위치(h, w), 방향(dir), 현재까지 잡아먹은 물고기 번호의 합(sum), 물고기가 저장된 2차원배열(Fish[][] map)을 받습니다.
  2. max값은 dfs 시작할 때 항상 갱신해도 상관이 없기 때문에 항상 갱신하도록 했습니다.
  3. 물고기는 번호 순서대로 움직이기 때문에 priorityQueue에 물고기를 넣어주었습니다. 이 때, 새로운 Fish를 생성하지 않고 map에 있는 기존의 Fish를 가리키도록 했습니다.
  4. 물고기를 이동시킵니다. 이동 할 때, 이동한 자리가 빈칸인 경우와 다른 물고기가 있는 경우로 구분해서 값을 수정해주었습니다.
  5. 상어의 이동이 가능한지 보면서 dfs를 진행해주었습니다. 이 때, map의 값이 바뀌기 때문에 깊은 복사를 이용해서 map객체를 새로 만들어서 인자로 넘겨주었습니다.

@Ukj0ng
Copy link

Ukj0ng commented Apr 21, 2025

궁금한 민호와 청소년 상어의 풀이가 생각보다 간단하고 복잡하지 않아서 문제를 좀 있는 그대로 보려고 노력해야겠습니다. 고생하셨습니다~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants