Skip to content

[이준희-12주차 알고리즘 스터디] #18

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 16 commits into
base: junhee325/week12
Choose a base branch
from

Conversation

JHLEE325
Copy link
Contributor

🚀 싸피 15반 알고리즘 스터디 12주차 [이준희]

📌 문제 풀이 개요

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

✅ 문제 해결 여부

  • 문제 1
  • 문제 2
  • 문제 3
  • 문제 4
  • 문제 5

💡 풀이 방법

문제 1: 파도반 수열

문제 난이도
실버 3

문제 유형
DP

접근 방식 및 풀이
삼각형이 나선형으로 이어졌을 때 n번 째 삼각형의 변의 길이를 구하는 문제였습니다.
dp 점화식을 구하여 풀었습니다.

long[] pado = new long[101];
		pado[1] = pado[2] = pado[3] = 1;
		for (int i = 4; i <= 100; i++) {
			pado[i] = pado[i - 2] + pado[i - 3];
		}

문제 2: 아기상어

문제 난이도
골드 3

문제 유형
그래프, 시뮬레이션

접근 방식 및 풀이
상어가 크기보다 작거나 같은 물고기를 먹을 수 있을 때 상어가 최대 몇마리의 물고기를 먹을 수 있는지 구하는 문제였습니다.
조건별로 시뮬레이션을 활용한 BFS로 풀었습니다.

while (true) { // 상어가 더이상 먹을 물고기가 없을 때 까지 반복 수행
			int move = bfs();
			if (move == -1) break; // 먹지 못한 경우

			res += move;

			if (s.size == s.eat) { // 상어가 충분히 먹으면 크기 증가
				s.size++;
				s.eat = 0;
			}
		}

먹을 수 있는 물고기의 경우 가장위, 가장 왼쪽이 우선순위가 높았기 때문에 전체 먹을 수 있는 물고기를 리스트에 저장하고 우선순위가 가장 높은 물고기를 먹을 수 있게 구현햇습니다.

while (!list.isEmpty()) {
			int size = list.size();
			step++;

			for (int i = 0; i < size; i++) {
				int[] cur = list.poll();

				for (int d = 0; d < 4; d++) {
					int dy = cur[0] + dir[d][0];
					int dx = cur[1] + dir[d][1];

					if (dy >= 0 && dy < n && dx >= 0 && dx < n && !visited[dy][dx]) {
						if (map[dy][dx] <= s.size) { // 이동 가능한 경우 이동
							visited[dy][dx] = true;

							if (map[dy][dx] != 0 && map[dy][dx] < s.size) {
								targets.add(new int[] { dy, dx }); // 물고기인 경우 먹을 수 있는 물고기 후보 처리
							}

							list.add(new int[] { dy, dx });
						}
					}
				}
			}

			if (!targets.isEmpty()) { // 먹이 우선순위에 따라 물고기 먹는 칸 구하기
				targets.sort((a, b) -> {
					if (a[0] != b[0]) return a[0] - b[0]; // 위쪽
					return a[1] - b[1]; // 왼쪽
				});

				int[] target = targets.get(0);
				s.y = target[0];
				s.x = target[1];
				s.eat++; // 먹은 횟수 증가
				map[s.y][s.x] = 0; // 먹은 물고기 칸 0으로 수정
				return step;
			}
		}

문제 3: 아기상어 2

문제 난이도
실버 2

문제 유형
그래프

접근 방식 및 풀이
맵에 상어와 빈칸이 존재하고 빈칸에서 상어칸 까지의 칸 개수를 안전거리라 했을 때 안전거리가 가장 큰 칸을 구하는 문제였습니다.
각 칸마다 BFS 를 사용하여 풀었습니다.

public static void bfs(int[] start) {
		Queue<int[]> list = new ArrayDeque<>();
		visited = new boolean[n][m];
		visited[start[0]][start[1]] = true;
		list.add(start);
		int step = 1; // step 별 bfs 수행으로 상어를 만나면 step을 안전거리로 갱신

		while (!list.isEmpty()) {
			int size = list.size();
			for (int s = 0; s < size; s++) {
				int[] cur = list.poll();
				for (int i = 0; i < 8; i++) {
					int dy = cur[0] + dir[i][0];
					int dx = cur[1] + dir[i][1];

					if (dy >= 0 && dy < n && dx >= 0 && dx < m) {
						if (map[dy][dx] == 1) {
							dist = Math.max(dist, step);
							return;
						} else if (!visited[dy][dx]) {
							visited[dy][dx] = true;
							list.add(new int[] { dy, dx });
						}
					}
				}
			}
			step++;
		}
	}

문제 4: 동전 1

문제 난이도
골드 4

문제 유형
DP

접근 방식 및 풀이
동전의 갯수와 그 가치가 주어졌을 때 특정 가격을 만들 수 있는 경우의 수를 구하는 문제였습니다. 각 동전의 사용갯수 제한이 없었기 때문에 낮은 가격부터 채우는 DP를 활용했습니다.

for (int i = 0; i < n; i++) {
                for (int j = coin[i]; j <= max; j++) { // 가장 낮은 가격부터
                    val[j] += val[j - coin[i]]; //dp 계산
                }
            }

문제 5 : 서강그라운드

문제 난이도
골드 5

문제 유형
그래프

접근 방식 및 풀이
특정위치에 떨어진 예은이가 이동 가능한 거리가 주어졌을 때 각 노드들을 방문하여 얻을 수 있는 아이템 개수의 총합을 구하는 문제였습니다.
플로이드 - 워셜을 활용하는 문제로 선정했었으나 다익스트라가 더 적합해보여 다익스트라를 활용해 풀었습니다.

static void dijkstra(int start) { // pq 를 사용한 다익스트라
		Queue<Node> pq = new PriorityQueue<>();
		boolean[] visited = new boolean[n + 1];
		int[] dist = new int[n + 1];
		Arrays.fill(dist, 20);
		dist[start] = 0;
		pq.offer(new Node(start, 0));
		int tmp=0;

		while (!pq.isEmpty()) {
			int curidx = pq.poll().idx;
			if (visited[curidx])
				continue;

			visited[curidx] = true;

			for (Node n : graph[curidx]) {
				if (dist[n.idx] > dist[curidx] + n.weight) {
					dist[n.idx] = dist[curidx] + n.weight;

					pq.offer(new Node(n.idx, dist[n.idx]));
				}
			}
		}
		
		for(int i=1;i<=n;i++) { // 다익스트라 종료 후 거리 판단하여 아이템갯수 추가
			if(dist[i]<=m) {
				tmp+=item[i];
			}
		}

		res = Math.max(res, tmp);
	}

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.

1 participant