Skip to content

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

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/week15
Choose a base branch
from

Conversation

JHLEE325
Copy link
Contributor

@JHLEE325 JHLEE325 commented May 3, 2025

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

📌 문제 풀이 개요

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

✅ 문제 해결 여부

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

💡 풀이 방법

문제 1: 점프왕 쩰리 (Small)

문제 난이도
실버 4

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

접근 방식 및 풀이
0,0 에서 시작하여 n,n 까지의 이동 가능 여부에 따라 haruharu, hing 을 출력하는 문제였습니다.
dfs 구현하여 풀었습니다.

public static void dfs(int x, int y) {
        if (x < 0 || y < 0 || x >= N || y >= N || visited[x][y]) {
            return; // 이동 가능 유효성 검사
        }

        visited[x][y] = true;

        if (map[x][y] == -1) {
            found = true;
            return;
        }

        int jump = map[x][y];
        dfs(x + jump, y); // 아래 이동
        dfs(x, y + jump); // 오른쪽 이동
    }

문제 2: 감시

문제 난이도
골드 3

문제 유형
시뮬레이션

접근 방식 및 풀이
총 5가지의 각각의 방향을 감시하는 CCTV가 있을 때 사각지대를 구하는 문제였습니다. 모든 경우를 탐색하는 브루트포스 문제로 시뮬레이션을 구현하여 풀었습니다.

static void simulate(int idx, int[][] map) {
        if (idx == cams.size()) { // 카메라 다 확인한 경우
            int tmp = 0;
            for (int i = 0; i < n; i++) { // 사각지대 체크
                for (int j = 0; j < m; j++) {
                    if (map[i][j] == 0) {
                        tmp++;
                    }
                }
            }
            result = Math.min(result, tmp); // 최소값으로 갱신
            return;
        }

        camera c = cams.get(idx);
        int[][] backup = copy(map); // 백트래킹위해 현재 상태 따로 저장

        for (int d = 0; d < 4; d++) { // 카메라 1,3,4의 경우에는 4번 시행
            watch(c, map, d);		  // 카메라 2의 경우 2번 시행, 5는 1번 시행
            simulate(idx + 1, map);
            map = copy(backup);
            if (c.type == 2 && d == 1) break;
            if (c.type == 5) break;
        }
    }

    static void watch(camera c, int[][] map, int direction) {
        int type = c.type;
        int y = c.y;
        int x = c.x;

        if (type == 1) { // 1방향
            observe(map, y, x, direction);
        } else if (type == 2) { // 양방향 반대로
            observe(map, y, x, direction);
            observe(map, y, x, (direction + 2) % 4);
        } else if (type == 3) { // 양방향 직각으로
            observe(map, y, x, direction);
            observe(map, y, x, (direction + 1) % 4);
        } else if (type == 4) { // 3방향
            observe(map, y, x, direction);
            observe(map, y, x, (direction + 1) % 4);
            observe(map, y, x, (direction + 2) % 4);
        } else if (type == 5) { // 4방향
            for (int d = 0; d < 4; d++) {
                observe(map, y, x, d);
            }
        }
    }

    static void observe(int[][] map, int y, int x, int d) {
        int ny = y + dir[d][0];
        int nx = x + dir[d][1];

        while (ny >= 0 && ny < n && nx >= 0 && nx < m) { // 맵 끝이나 벽까지 감시
            if (map[ny][nx] == 6) break;
            if (map[ny][nx] == 0) map[ny][nx] = 7;
            ny += dir[d][0];
            nx += dir[d][1];
        }
    }

문제 3: 빗물

문제 난이도
골드 5

문제 유형
시뮬레이션

접근 방식 및 풀이
n까지의 각 칸의 지면의 높이가 주어질때 지면으로 둘러쌓여서 빗물이 고일 수 있는 영역의 넓이를 구하는 문제였습니다. 각 영역별로 왼쪽 최대높이, 오른쪽 최대높이를 구하여 풀이했습니다.

 left[0]=height[0];
        for(int i=1;i<m;i++) { // 왼쪽 벽 높이 계산
        	left[i] = Math.max(left[i-1], height[i]);
        }
        right[m-1]=height[m-1];
        for(int i=m-2;i>=0;i--) { // 오른쪽 벽 높이 계산
        	right[i] = Math.max(right[i+1], height[i]);
        }
        
        for(int i=0;i<m;i++) { // 두 벽 중 낮은 곳으로 각 위치의 물 양 계산
        	int water = Math.min(left[i], right[i]) - height[i];
        	if(water>0)
        		result+=water;
        }

문제 4: 마법사 상어와 파이어볼

문제 난이도
골드 4

문제 유형
시뮬레이션

접근 방식 및 풀이
파이어 볼의 이동, 이동 후의 처리에 관한 시뮬레이션 문제였습니다.
파이어 볼 클래스를 만들어 관리 하였고 제시된 규칙에 따라 시뮬레이션을 수행하였습니다.

while (K-- > 0) {
            // 파이어볼 이동
            for (Fireball fb : fireballs) {
                int nr = (fb.r + dr[fb.d] * fb.s % N + N) % N;
                int nc = (fb.c + dc[fb.d] * fb.s % N + N) % N;
                map[nr][nc].add(new Fireball(nr, nc, fb.m, fb.s, fb.d));
            }

            // 처리
            fireballs.clear();
            for (int r = 0; r < N; r++) {
                for (int c = 0; c < N; c++) {
                    if (map[r][c].size() == 0) continue;

                    if (map[r][c].size() == 1) {
                        fireballs.add(map[r][c].get(0));
                    } else {
                        int sumM = 0, sumS = 0;
                        boolean allEven = true, allOdd = true;

                        for (Fireball fb : map[r][c]) {
                            sumM += fb.m;
                            sumS += fb.s;
                            if (fb.d % 2 == 0) allOdd = false;
                            else allEven = false;
                        }

                        int newM = sumM / 5;
                        if (newM == 0) {
                            map[r][c].clear();
                            continue;
                        }

                        int newS = sumS / map[r][c].size();
                        int[] newDirs = (allEven || allOdd) ? new int[]{0, 2, 4, 6} : new int[]{1, 3, 5, 7};
                        for (int d : newDirs) {
                            fireballs.add(new Fireball(r, c, newM, newS, d));
                        }
                    }
                    map[r][c].clear();
                }
            }
        }

문제 5 : 2048

문제 난이도
골드 1

문제 유형
시뮬레이션

접근 방식 및 풀이
문제풀이 하지 못했습니다.


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