구름톤 챌린지 통증 (2)

[시행 착오]

아래 코드는 처음에 제출한 오답코드이다. 처음엔 간단한 문제겠구나 하고 풀었다가 테스트 케이스에서 오답을 만나고 내가 뭘 잘못했을까 고민해봤다. 무조건 N을 큰 수부터 빼는게 중요한것이 아니고 결국은 N==0이 되는것이 가장 중요하다는것을 깨달았다. 머리로는 대충 알겠지만 도저히 스스로 풀 수가 없었다. 슬슬 모든 문제들이 풀이를 보지 않고는 풀수가 없는 단계까지 왔다. 나의 한계를 만난것이다. 그래서 풀이를 보며 코드 한 라인, 한 라인 나아가며 뜯어본 결과 이해는 됬으나 스스로 그 풀이를 작성할 수가 없어서 참고해가며 풀었다. 배낀수준이지만 이렇게라도 하면 실력이 늘것이라고 생각한다. 

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

class Main {
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		Integer N = Integer.parseInt(st.nextToken());
		st = new StringTokenizer(br.readLine(), " ");
		Integer A = Integer.parseInt(st.nextToken());
		Integer B = Integer.parseInt(st.nextToken());
		int count = 0;
		boolean flag = true;
		while(flag) {
			if(N-B>=0) {
				N-=B;
				count++;
				flag = true;
				continue;
			} else {
				flag = false;
			}
			if(N-A>=0) {
				N-=A;
				count++;
				flag = true;
			} else {
				flag = false;
			}
		}
		if(N>0){
			count=-1;
		}
		System.out.println(N);
		System.out.println(count);
	}
}

[정답 코드]

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

class Main {
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		Integer N = Integer.parseInt(st.nextToken());
		st = new StringTokenizer(br.readLine(), " ");
		Integer A = Integer.parseInt(st.nextToken());
		Integer B = Integer.parseInt(st.nextToken());
		
		int[] dp = new int[N+1];
		
		//풀이에서는 MAX_VALUE로 초기화 했다. MAX_VALUE 가 아니라 N보다 큰값이면 다 가능하지 않을까 생각한다.
		for(int i=0;i<=N;i++) {
			dp[i] = Integer.MAX_VALUE;
		}
		dp[0] = 0;
		
		for(int i=0;i<=N;i++) {
			if(i-A>=0 && dp[i-A] != Integer.MAX_VALUE) {
				dp[i] = Math.min(dp[i], dp[i-A] + 1);
			}
			//N-A 를 했을때보다 횟수가 더 적을경우 N-B로 한것을 선택한다.
			if(i-B>=0 && dp[i-B] != Integer.MAX_VALUE) {
				dp[i] = Math.min(dp[i], dp[i-B] + 1);
			}
		}
		
		//for문 끝까지 돌렸을때 dp[N] 값이 여전히 MAX_VALUE라면 -1을 출력한다.
		System.out.println(dp[N] != Integer.MAX_VALUE ? dp[N] : -1);
	}
}

구름톤 챌린지 GameJam

[느낀점]

결국 이 문제도 풀이를 보며 풀었다. 풀이를 보지 않고는 나는 도저히 풀 수 없는 레벨이였다. 처음에 이 문제를 풀었을 때는 코드가 현재 정답코드의 2배이상이였다. static 매서드로 함수를 만들어서 풀 생각을 못해서 각 goorm 과 player의 게임 을 2번 진행해서 2배가 되버린것이다. 풀이를 참고해가며 문제를 다 작성하고 제출을 했는데 컴파일 오류가 계속나는 것이다. 그래서 chatgpt에 물어보고 구글링을 1시간넘게 계속했다. chatgpt도 문제가 없다고 말해서 이유를 못찾다가 알고보니 매서드를 만들어서 쓰려면 static 으로 만들어야했는데 나는 public static void main 안에 다 담아버려서 그랬던거였다. 아래는 정답 코드이다.

 

[정답코드]

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

class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        int N = Integer.parseInt(st.nextToken());

        //goorm과 player의 시작 위치 생성
        st = new StringTokenizer(br.readLine(), " ");
        int[] goormPos = {Integer.parseInt(st.nextToken()) - 1, Integer.parseInt(st.nextToken()) - 1};
        //bolean 배열은 기본적으로 false로 초기화된다
        boolean[][] goormVisited = new boolean[N][N];
        st = new StringTokenizer(br.readLine(), " ");
        int[] playerPos = {Integer.parseInt(st.nextToken()) - 1, Integer.parseInt(st.nextToken()) - 1};
        boolean[][] playerVisited = new boolean[N][N];


        //보드판 생성
        String[][] board = new String[N][N];
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine(), " ");
            for (int j = 0; j < N; j++) {
                board[i][j] = st.nextToken();
            }
        }
        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);
        }
        
    }

        //dx/dy 기법을 사용해 행렬에서 방향을 관리, 문제가 문자열형태로 주기때문에 map을 사용

    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});
        }
    };


        //좌표에서 이동을 하다 보드판을 넘어갔을 경우 반대편으로 넘어가는 함수
        static int setPos(int a,int N) {
            if (a == -1) return N - 1;
            if(a == N) return 0;
            return a;
        }

        //게임을 진행하다 종료됬을때의 점수를 return 해주는 함수
        static int move(int[] pos, boolean[][] visited, int score, String[][] board, int N) {

            //말의 위치
            int x = pos[0];
            int y = pos[1];
            //방문한 위치는 true로 전환
            visited[x][y] = true;
            //score는 초기에 1점

            boolean flag = true;
            //flag가 false가 되면 while문 종료
            while(flag) {
                String command = board[x][y];
                //command의 첫번째 문자
                int distance = Integer.parseInt(command.substring(0, command.length() - 1));
                //command의 두번째 문자
                String direction = command.substring(command.length() - 1);
                //distance만큼 direction 방향으로 이동
                for(int i=0;i<distance;i++) {
                    //이 부분이 약간 이해가 헷갈린다
                    x+=directions.get(direction)[0];
                    y+=directions.get(direction)[1];
                    x = setPos(x, N);
                    y = setPos(y, N);

                    if(!visited[x][y]){
                        visited[x][y] = true;
                        score++;
                    } else {
                        flag = false;
                        break;
                    }
                }
            }
            return score;
        }

}

구름톤 챌린지 폭탄 구현하기(2)

 

[느낀점]

7일차에 풀었던 8방탐색문제보다 쉬운버전인 4방탐색문제다. 8방탐색을 한번 풀어서 그런걸까 더 쉽게 느껴졌다. 하지만 여전히 코드는 depth가 깊어 스마트하지 못한 코드같다. 완전탐색문제를 dx/dy 테크닉으로 풀어야 될것같은데 여전히 어려워서 if문 도배로 해버렸다.

 

[결과 코드]

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

class Main {
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		int N = Integer.parseInt(st.nextToken());
		int K = Integer.parseInt(st.nextToken());
		String[][] map = new String[N][N];
		int[][] score = new int[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();
				score[i][j] = 0;
			}
		}
		
		int max = 0;
		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;
			if(y-1>=0){
				if(map[y-1][x].equals("@")){
					score[y-1][x]+=2;
				} else if (map[y-1][x].equals("0")){
					score[y-1][x]++;
				}
			}
			if(y+1<N){
				if(map[y+1][x].equals("@")){
					score[y+1][x]+=2;
				} else if (map[y+1][x].equals("0")){
					score[y+1][x]++;
				}
			}
			if(x-1>=0){
				if(map[y][x-1].equals("@")){
					score[y][x-1]+=2;
				} else if (map[y][x-1].equals("0")){
					score[y][x-1]++;
				}
			}
			if(x+1<N){
				if(map[y][x+1].equals("@")){
					score[y][x+1]+=2;
				} else if (map[y][x+1].equals("0")){
					score[y][x+1]++;
				}
			}
			if(map[y][x].equals("@")){
				score[y][x]+=2;
			} else if (map[y][x].equals("0")) {
				score[y][x]++;
			}
		}
		
		for(int i=0;i<N;i++) {
			for(int j=0;j<N;j++) {
				if(score[i][j]>=max) {
					max=score[i][j];
				}
			}
		}
		System.out.println(max);
		
	}
}

구름톤 챌린지 통증

[느낀점]

난이도가 갑자기 엄청 쉬워져서 당황했다. 그나마 평소에 사용안하던 StringTokenizer 를 사용해서 실력향상에 도움이 됬다고 생각한다. 다음날 공개된 풀이를 보니 그리디 문제였다. 그리디 알고리즘중에 쉬운 문제가 나온 것 같다. 좀 더 어렵게 나왔다면 내가 푼 방식으로는 더 복잡하게 풀게 될것같다.

 

[결과 코드]

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

class Main {
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		int N = Integer.parseInt(st.nextToken());
		int answer = 0;
		while(N!=0) {
			if(N-14>=0) {
				N-=14;
				answer++;
			} else if (N-7>=0) {
				N-=7;
				answer++;
			} else if(N-1>=0){
				N-=1;
				answer++;
			}
		}
		System.out.println(answer);
	}
}

구름톤 챌린지 구름 찾기 깃발

[느낀점]

문제를 보자마자 아 이거 나 혼자 못풀겠다! 싶었다. 저번에도 프로그래머스에서 지뢰찾기 문제를 푼 적이 있었는데 그때도 매우 어렵게 여러블로그 찾아가며 풀었었다. 8방탐색이란걸 해서 풀면 나름 쉽게 풀린다고 한다. 구름에서 제공한 풀이를보면 dx/dy 탐색법을 사용하면 된다고 한다. 하지만 dx/dy 탐색법이란걸 봐도 이해가 잘 안가서 나만의 방법으로 했다. 풀이가 되게 간단하고 허접하다. 각 방향별 상,하,좌,우, 대각선 총 8개의 if문이 들어가서 코드가 약간 더럽다. 다음엔 dx/dy 탐색법을 사용해 볼거라고 다짐해보며 일단 현재 풀이의 만족하기로 했다.

 

[결과 코드]

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

class Main {
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		int N = Integer.parseInt(st.nextToken());
		int K = Integer.parseInt(st.nextToken());
		int[][] arr = new int[N][N];
		
		for(int i=0;i<N;i++){
			st = new StringTokenizer(br.readLine(), " ");
			for(int j=0;j<N;j++){
				if(Integer.parseInt(st.nextToken())==1) {
					arr[i][j] = -1;
				} else {
					arr[i][j] = 0;
				}
			}
		}
		for(int i=0;i<N;i++){
			int score = 0;
			for(int j=0;j<N;j++){
				if(arr[i][j]==0){
					if(i-1>=0){
						if(arr[i-1][j]==-1) arr[i][j]++;
					}
					if(i+1<N){
						if(arr[i+1][j]==-1) arr[i][j]++;
					}
					if(j-1>=0){
						if(arr[i][j-1]==-1) arr[i][j]++;
					}
					if(j+1<N){
						if(arr[i][j+1]==-1) arr[i][j]++;
					}
					if(i-1>=0 && j-1>=0){
						if(arr[i-1][j-1]==-1) arr[i][j]++;
					}
					if(i-1>=0 && j+1<N){
						if(arr[i-1][j+1]==-1) arr[i][j]++;
					}
					if(i+1<N && j-1>=0){
						if(arr[i+1][j-1]==-1) arr[i][j]++;
					}
					if(i+1<N && j+1<N){
						if(arr[i+1][j+1]==-1) arr[i][j]++;
					}
				}
			}
		}
		
		int answer = 0;
		for(int i=0;i<N;i++){
			for(int j=0;j<N;j++){
				if(arr[i][j]==K) {
					answer++;
				}
			}
		}
		System.out.println(answer);
	}
}

+ Recent posts