Skip to content

[강신지-12주차 알고리즘 스터디] #20

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

Conversation

ksinji
Copy link
Contributor

@ksinji ksinji commented Apr 13, 2025

🚀 싸피 15반 알고리즘 스터디 12주차 [강신지]

📌 문제 풀이 개요

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

✅ 문제 해결 여부

  • 문제 1: 파도반수열
  • 문제 2: 아기 상어
  • 문제 3: 아기 상어 2
  • 문제 4: 동전 1
  • 문제 5: 서강 그라운드

💡 풀이 방법

문제 1: 파도반수열

문제 난이도
실버 3

문제 유형
DP

접근 방식 및 풀이
규칙을 찾아 DP로 해결하였습니다.

long[] dp = new long[N+1];			
			dp[1] = 1;
			dp[2] = 1;
			dp[3] = 1;
			dp[4] = 2;
			
			for (int i=5; i<N+1; i++) {
				dp[i] = dp[i-1]+dp[i-5];
			}

문제 2: 아기 상어

문제 난이도
골드 3

문제 유형
구현

접근 방식 및 풀이
아기 상어가 물고기를 잡아먹을 수 있는 시간을 구하는 문제였습니다.
주어진 조건에 따라 타겟 물고기를 BFS로 구하며 더 이상 먹을 수 있는 물고기가 없을 때까지 시간을 계산했습니다.

    // BFS를 통해 먹을 수 있는 물고기 후보 중 최단거리, 위, 왼쪽 순으로 x, y좌표, 거리 return
    // 찾지 못하면 null return
    public static int[] bfs(int startX, int startY) {
        boolean[][] visited = new boolean[N][N];
        Queue<int[]> queue = new LinkedList<>();
        queue.offer(new int[]{startX, startY, 0});
        visited[startX][startY] = true;
        
        List<int[]> fish = new ArrayList<>();
        int minDistance = Integer.MAX_VALUE;
        
        while(!queue.isEmpty()){
            int[] cur = queue.poll();
            int x = cur[0], y = cur[1], dist = cur[2];
            
            // 만약 현재까지의 최단거리보다 더 먼 경로라면 continue
            if(dist > minDistance) continue;
            
            // 먹을 수 있는 물고기일 경우
            if(map[x][y] != 0 && map[x][y] < sharkSize) {
                // 첫 후보 발견시 minDistance 업데이트하고
            	// 기존 물고기 리스트 갱신
                if(dist < minDistance) {
                    minDistance = dist;
                    fish.clear();
                    fish.add(new int[]{x, y});
                } else if(dist == minDistance) { // 같은 거리에 여러 후보가 있다면 리스트에 추가
                	fish.add(new int[]{x, y});
                }
            }
            
            for (int i = 0; i < 4; i++){
                int nx = x + dx[i];
                int ny = y + dy[i];
                if(isOK(nx, ny) && !visited[nx][ny] && map[nx][ny] <= sharkSize) {
                    visited[nx][ny] = true;
                    queue.offer(new int[]{nx, ny, dist + 1});
                }
            }
        }
        
        if(fish.isEmpty()) return null;
        
        // 행 번호가 가장 작은 물고기, 행 번호가 같으면 열 번호가 가장 작은 물고기 선택
        Collections.sort(fish, new Comparator<int[]>() {
            public int compare(int[] o1, int[] o2){
                if(o1[0] != o2[0]) 
                    return o1[0] - o2[0];
                return o1[1] - o2[1];
            }
        });
        
        int[] chosen = fish.get(0);
        return new int[]{chosen[0], chosen[1], minDistance};
    }

문제 3: 아기 상어 2

문제 난이도
실버 2

문제 유형
구현

접근 방식 및 풀이
아기 상어와의 거리(안전 거리)의 최댓값을 구하는 문제였습니다.
BFS로 해결했습니다.

		while(!q.isEmpty()) {
			int[] cur = q.poll();
			
			for (int j=0; j<8; j++) {
				int nx = cur[0] + dx[j];
				int ny = cur[1] + dy[j];
				
				if (!isOK(nx, ny) || visited[nx][ny] >= cnt) continue;
				
				q.add(new int[] {nx, ny});
				visited[nx][ny]++;
				
				if (visited[nx][ny] == 1) {
					result[nx][ny] = result[cur[0]][cur[1]]+1;
				} else {
					result[nx][ny] = Math.min(result[cur[0]][cur[1]]+1, result[nx][ny]);
				}
			}
		}

문제 4: 동전 1

문제 난이도
골드 4

문제 유형
DP

접근 방식 및 풀이
n가지 동전을 사용해 가치의 합이 k원이 되도록 하는 경우의 수를 구하는 문제였습니다.
1차원 dp 배열을 사용해 해결하였습니다.

		int[] dp = new int[K+1];
		dp[0] = 1;
		
		for (int i=coin[1]; i<K+1; i+=coin[1]) {
			dp[i] = 1;
		}
		
		for (int i=2; i<N+1; i++) {
			for (int j=K; j>=0; j--) {
				if (coin[i] > j) continue;
				for (int k=j-coin[i]; k>=0; k-=coin[i]) dp[j] += dp[k];
			}
		}

문제 5 : 서강 그라운드

문제 난이도
골드 4

문제 유형
플로이드 워셜

접근 방식 및 풀이
양방향 그래프와 수색 가능 범위가 주어지고 얻을 수 있는 아이템의 최대 개수를 구하는 문제였습니다.
모든 정점 쌍에 대해 중간 정점을 하나씩 고려하며 최단 거리를 갱신하는 플로이드 워셜 알고리즘을 사용하였습니다.

// k 정점을 거쳐가는 경우 모두 계산
        for (int i=1; i < N+1; i++) { // 중간 정점
        	 for (int j=1; j < N+1; j++) {
        		 if (dist[j][i] == 10000000) continue;
        		 for (int k=1; k < N+1; k++) {
        			 if (dist[i][k] == 10000000) continue;
        			 if (dist[j][i] + dist[i][k] < dist[j][k]) {
        				 dist[j][k] = dist[j][i] + dist[i][k];
        			 }
        		 }
        	 }
        }

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