본문 바로가기
알고리즘/문제 풀이

[☁️ 구름톤 챌린지] 2주차 학습일지 - 2

by 위대한초밥V 2023. 8. 27.

문제 8. 통증

그리디 문제이다. 

그리디 문제의 대명사인 '동전' 문제처럼 가장 큰수부터 빼가면서 문제를 풀이하면 된다.

import java.io.*;
import java.util.*;

class Main {
	static int N;
	static int[] items = {1, 7, 14};
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		N = Integer.parseInt(br.readLine());
		
		int result = 0;
		int i = items.length-1;
		while(N > 0) {
			if(N == 0) {
				break;
			}
			if(N - items[i] >= 0) {
				N -= items[i];
				result += 1;
			}
			else {
				i -= 1;
			}
		}
		System.out.println(result);
	}
}

⚡️ 몫과 나머지를 이용해서 풀이해도 된다.

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        int N = scanner.nextInt();
        scanner.close();

        int ans = 0;
        int[] painKiller = {14, 7, 1};
        for (int i : painKiller) {
            ans += N / i;	// 큰 단위로 나누었을 때, 몫
            N %= i;			// 나머지 -> 다음으로 큰 단위로 나눈다.
        }
        System.out.println(ans);
    }
}

 

문제 9. 폭탄 구현하기 (2)

완전 탐색 문제이다. 

원래 위치와 다음 폭탄의 위치를 함께 확인해야 한다. 본인은 현재 좌표를 기준으로 동서남북에 위치한 폭탄의 위치를 확인하고, 본인 좌표를 확인해서 코드가 다음처럼 길어졌다.

for(int i = 0; i < K; i++) {
	st = new StringTokenizer(br.readLine());
	int y = Integer.parseInt(st.nextToken()) - 1;
	int x = Integer.parseInt(st.nextToken()) - 1;
			
	for(int j = 0; j < 4; j++) {
		int n_y = y + dy[j];
		int n_x = x + dx[j];
				
		if(n_y < 0 || n_y >= N || n_x < 0 || n_x >= N) {
			continue;
		}
				
		if(map[n_y][n_x].equals("#")) {
			continue;
		}
				
		if(map[n_y][n_x].equals("@")) {
			result[n_y][n_x] += 2;
		}
				
		if(map[n_y][n_x].equals("0")) {
			result[n_y][n_x] += 1;
		}
	}
			
	if(map[y][x].equals("#")) {
		continue;
	}
				
	if(map[y][x].equals("@")) {
		result[y][x] += 2;
	}
				
	if(map[y][x].equals("0")) {
		result[y][x] += 1;
	}
}

생각해보니 본인의 현재 위치는 ⚡️0,0⚡️으로 나타낼 수 있다.

따라서 다음과 같이 코드를 수정할 수 있다.

import java.io.*;
import java.util.*;

class Main {
	static int N, K;
	static String[][] map;
	static int[][] result;
	static int[] dy = {0,0,1,0,-1};
	static int[] dx = {0,1,0,-1,0};
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		
		st = new StringTokenizer(br.readLine());
		N = Integer.parseInt(st.nextToken());
		K = Integer.parseInt(st.nextToken());
		
		map = new String[N][N];
		
		for(int i = 0; i < N; i++) {
			st = new StringTokenizer(br.readLine());
			for(int j = 0; j < N; j++) {
				map[i][j] = st.nextToken();
			}
		}
		
		result = new int[N][N];
		
		for(int i = 0; i < K; i++) {
			st = new StringTokenizer(br.readLine());
			int y = Integer.parseInt(st.nextToken()) - 1;
			int x = Integer.parseInt(st.nextToken()) - 1;
			
			for(int j = 0; j < 5; j++) {
				int n_y = y + dy[j];
				int n_x = x + dx[j];
				
				if(n_y < 0 || n_y >= N || n_x < 0 || n_x >= N) {
					continue;
				}
				
				if(map[n_y][n_x].equals("#")) {
					continue;
				}
				
				if(map[n_y][n_x].equals("@")) {
					result[n_y][n_x] += 2;
				}
				
				if(map[n_y][n_x].equals("0")) {
					result[n_y][n_x] += 1;
				}
			}
		}
		
		int max_value = 0;
		for(int i = 0; i < N; i++) {
			for(int j = 0; j < N; j++) {
				max_value = Math.max(max_value, result[i][j]);
			}
		}
		
		System.out.println(max_value);
	}
}

문제 10. GameJam

이 문제는 계속 안풀려서 답을 봤다.🥲

확인해보니 접근 방식은 맞았는데 풀이 과정 중에 구현 실수를 해서 정답이 되지 않았다. 

주석을 달면서 풀이를 이해해보겠다!

import java.util.*;

public class Main {

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int N = scanner.nextInt();
		int[] goormPos = {scanner.nextInt() - 1, scanner.nextInt() - 1};
		boolean[][] goormVisited = new boolean[N][N];	// goorm 방문 표시
		int[] playerPos = {scanner.nextInt() - 1, scanner.nextInt() - 1};
		boolean[][] playerVisited = new boolean[N][N];	// player 방문 표시

		String[][] board = new String[N][N];
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				board[i][j] = scanner.next();
			}
		}

		int goormScore = move(goormPos, goormVisited, 1, board, N);
		int playerScore = move(playerPos, playerVisited, 1, board, N);

		if (goormScore > playerScore) {
			System.out.println("goorm " + goormScore);
		} else if (goormScore < playerScore) {
			System.out.println("player " + playerScore);
		}
		scanner.close();
	}


	public static int set_Pos(int a, int N) {
			if (a == -1) return N - 1;	// 0보다 작은 곳으로 이동하면 반대편으로 가도록
			if (a == N) return 0;		// N보다 큰 곳으로 이동하면 반대편으로 가도록
			return a;
	}
	
	static HashMap<String, int[]> directions = new HashMap<String, int[]>() {
		{
			put("U", new int[]{-1, 0});
			put("D", new int[]{1, 0});
			put("L", new int[]{0, -1});
			put("R", new int[]{0, 1});
		}
	};

	public static int move(int[] pos, boolean[][] visited, int score, String[][] board, int N) {
			int x = pos[0];
			int y = pos[1];
			visited[x][y] = true;
			boolean flag = true;

			while (flag) {
					String command = board[x][y];
                    // distance는 direction 문자열 앞까지를 말한다.
					int distance = Integer.parseInt(command.substring(0, command.length() - 1));
                    // 가장 마지막에 위치한 것은 direction 
					String direction = command.substring(command.length() - 1);

					for (int i = 0; i < distance; i++) {
							x += directions.get(direction)[0];
							y += directions.get(direction)[1];
							x = set_Pos(x, N);
							y = set_Pos(y, N);

							if (!visited[x][y]) {
									visited[x][y] = true;
									score += 1;
							} else {
									flag = false;	// 이미 방문했다면 게임이 종료된다.
									break;
							}
					}
			}
			return score;
	}

}

나의 시도는 게임을 진행하다가 게임 종료 조건을 만나면 바로 게임을 현재 게임 참여자의 flag를 바꿔서 게임을 종료시키는 것이었는데, goorm과 player의 score 변수를 두개로 관리하다보니 풀이가 복잡해졌다. 이 풀이는 score를 return 해서 goorm과 player 중 승자를 비교하는데 이 풀이가 더 적합하다고 생각한다.

 

벌써 2주차가 지났다. 

하루하루 블록이 쌓아가는 것 보면 뿌듯하다.👊 다음주는 탐색과 DP 문제를 푸는데 평소에 연습이 필요하다고 생각했던 단원이라 더욱 기대된다. 그럼 마지막까지 화이팅~

반응형