ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 1149, 12852, 17135
    Java/코딩테스트 2023. 7. 21. 09:22

    https://www.acmicpc.net/problem/1149

     

    1149번: RGB거리

    첫째 줄에 집의 수 N(2 ≤ N ≤ 1,000)이 주어진다. 둘째 줄부터 N개의 줄에는 각 집을 빨강, 초록, 파랑으로 칠하는 비용이 1번 집부터 한 줄에 하나씩 주어진다. 집을 칠하는 비용은 1,000보다 작거나

    www.acmicpc.net

    동적계획법 문제

    - 각 색칠 비용 저장할 2차원 배열 cost

    - DP[ i ] [ j ] : i번째 집에  j색(0 빨 - 1 파 - 2 초) 칠했을 때 드는 최소 비용 

    - 이웃하는 집끼리 색 안겹치게 하는 것만 기억하면 쉬운 문제 

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.StringTokenizer;
    
    public class p1149 {
    
        public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            int n = Integer.parseInt(br.readLine());
            int answer = Integer.MAX_VALUE;
    
            int[][] costs = new int[n][3];
            int[][] DP = new int[n][3];
    
            for (int i = 0; i < n; i++) {
                StringTokenizer st = new StringTokenizer(br.readLine());
                for (int j = 0; j < 3; j++) {
                    costs[i][j] = Integer.parseInt(st.nextToken());
                }
            }
    
            System.arraycopy(costs[0], 0, DP[0], 0, 3);
    
            for (int i = 1; i < n; i++) {
                for (int j = 0; j < 3; j++) {
                    DP[i][j] = Math.min(DP[i-1][(j+1)%3] , DP[i-1][(j+2)%3]) + costs[i][j];
                }
            }
    
            for (int j = 0; j < 3; j++) {
                answer = Math.min(answer, DP[n-1][j]);
            }
            System.out.println(answer);
        }
    }

     


    https://www.acmicpc.net/problem/12852

     

    12852번: 1로 만들기 2

    첫째 줄에 1보다 크거나 같고, 106보다 작거나 같은 자연수 N이 주어진다.

    www.acmicpc.net

    동적계획법 문제 2

    - 처음엔 이 경로를 쭉 출력해주는 걸 보고 탐색을 해야하나 했지만 시간제한 0.5초이다. 즉, 동적계획법으로 풀어야한다..

    - before[] 을 사용해주는걸로 손쉽게 풀 수 있는 문제였다... 이게 생각이 안나서 한참 고민하다 검색하여 다른 사람의 코드를 보고 푼 문제이다. 

    - DP[] 에는 해당 숫자가 되기까지 걸리는 최소 연산횟수를 저장한다. 

    - before[] 배열에는 i 다음에 올 숫자를 저장한다고 생각하면된다. 예를 들어, before[ 6 ] : 2이므로 나중에 경로 출력할 때 역순으로 6 - >  2 이런식으로 출력하면 된다.

    import java.util.*;
    public class p12852 {
        // 복잡하게 그래프 탐색까지 가지 말고..그냥 DP 선에서 끝낼 수 있다. before[] 배열 하나 만들어서!
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            int[] DP = new int[n+1];
            int[] before = new int[n+1];
    
            DP[1] = 0;
            before[1] = 1;
    
            for (int i = 2; i <= n; i++) {
                DP[i] = DP[i-1] + 1;
                before[i] = i-1;
                if (i % 3 == 0) {
                    if (DP[i] > DP[i/3] + 1) {
                        DP[i] = DP[i/3] + 1;
                        before[i] = i/3;
                    }
                }
                if (i % 2 == 0) {
                    if (DP[i] > DP[i/2] + 1) {
                        DP[i] = DP[i/2] + 1;
                        before[i] = i/2;
                    }
                }
            }
    
            System.out.println(DP[n]);
    
            while (n != 1) {
                System.out.print(n + " ");
                n = before[n];
            }
            System.out.print(1);
        }
    }

    https://www.acmicpc.net/problem/17135

     

    17135번: 캐슬 디펜스

    첫째 줄에 격자판 행의 수 N, 열의 수 M, 궁수의 공격 거리 제한 D가 주어진다. 둘째 줄부터 N개의 줄에는 격자판의 상태가 주어진다. 0은 빈 칸, 1은 적이 있는 칸이다.

    www.acmicpc.net

     

    - 삼성 A형 문제,, 항상 조건을 잘 봐야하는 문제이다. 

    이게 왜 실수했었냐면... pq에서 가장 우선순위가 높은 적을 먼저 죽이는데 각 사수마다 우선순위 높은 적이 같다면 그냥 같이 쏘는 것이었다. 나혼자 상상의 나래로 얘는 1순위 적 죽이고 다음 애가 만약 겹친담녀 다음 궁수는 2순위 적 죽이고 이런식으로 상상하였다.

    while (!pq.isEmpty()) 이렇게 주면서 정확도 한30%쯤인가.. 거기서 계속 막혔었다. 

    그리고 추가로 적과의 거리 정보 + 몇 번째 적인지 index 도 위치정보와 함께 저장해야 하는데 이것도 계속 고민했었다.

    근데 그냥 ... static class 하나 더 형성하면 쉽게 해결할 수 있었다. 그래서 위치정보 Pos 클래스와 더불어 Monster라는 코드도 썼다. 

    새로운 클래스 쓰는건 다른 분 코드 보다가 클래스에 저렇게 다 넣는거 보고 Pos만 만들줄 알고 ㅋㅋㅋ 클래스 하나 더 만들 줄 모르는 본인이 우스워졌다.. 

     

     

     

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.ArrayList;
    import java.util.PriorityQueue;
    import java.util.StringTokenizer;
    
    public class p17135 {
        static int[][] map;
        static int[] archerPos;
        static int row, col, shootDis, killCount;
        static ArrayList<Pos> enemyPos;
        public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            StringTokenizer st = new StringTokenizer(br.readLine());
    
            row = Integer.parseInt(st.nextToken());
            col = Integer.parseInt(st.nextToken());
            shootDis = Integer.parseInt(st.nextToken());
            killCount = 0;
    
            map = new int[row][col];
            archerPos = new int[3];
            enemyPos = new ArrayList<>();
    
            for (int i = 0; i < row; i++) {
                st = new StringTokenizer(br.readLine());
                for (int j = 0; j < col; j++) {
                    map[i][j] = Integer.parseInt(st.nextToken());
                    if (map[i][j] == 1) {
                        enemyPos.add(new Pos(i, j));
                    }
                }
            }
    
            chooseArcherPos(0,0 );
            System.out.println(killCount);
        }
    
        public static void chooseArcherPos(int depth, int start) {
            if (depth == 3) {
                killCount = Math.max(killCount, game());
                return;
            }
    
            for (int i = start; i < col; i++) {
                archerPos[depth] = i;
                chooseArcherPos(depth+1, i+1);
            }
        }
    
    
        // 시뮬레이션
        public static int game() {
            int count = 0;
            ArrayList<Pos> enemies = new ArrayList<>(enemyPos);
    
            while (!enemies.isEmpty()) {
                if (count >= enemyPos.size()) {
                    break;
                }
                ArrayList<Pos> temp = new ArrayList<>();
                boolean[] killed = new boolean[enemies.size()];
                for (int i = 0; i < 3; i++) {
                    Pos archer = new Pos(row, archerPos[i]);
                    PriorityQueue<Monster> pq = new PriorityQueue<>();
    
                    for (int e = 0; e < enemies.size(); e++) {
                        int dis = distance(archer, enemies.get(e));
                        if (dis <= shootDis) {
                            pq.add(new Monster(dis, e, enemies.get(e)));
                        }
                    }
    
                    // 여기때문에 실수...
                    if (!pq.isEmpty()) {
                        Monster poll = pq.poll();
                        if (!killed[poll.index]) {
                            killed[poll.index] = true;
                        }
                    }
                }
    
                for (int i = 0; i < enemies.size(); i++) {
                    if (!killed[i]) {
                        temp.add(enemies.get(i));
                    }
                    else {
                        count++;
                    }
                }
    
                enemies = new ArrayList<>(moveEnemy(temp));
    
            }
    
            return count;
        }
    
    
        // 적 관련 함수
        public static ArrayList<Pos> moveEnemy(ArrayList<Pos> copyEnemyPos) {
            ArrayList<Pos> temp = new ArrayList<>();
    
            for (Pos p : copyEnemyPos) {
                Pos next = new Pos(p.x + 1, p.y);
                if (canMoveTo(next)) {
                    temp.add(next);
                }
            }
            return temp;
        }
    
        public static boolean canMoveTo(Pos pos) {
            if (pos.x >= row) {
                return false;
            }
            return true;
        }
    
        // 거리계산 & 좌표 클래스 정의
        public static int distance(Pos x, Pos y) {
            return (Math.abs(x.x - y.x) + Math.abs(x.y - y.y));
        }
    
        static class Pos {
            int x;
            int y;
            public Pos(int x, int y) {
                this.x = x;
                this.y = y;
            }
    
        }
    
        static class Monster implements Comparable<Monster> {
            int distance;
            int index;
            Pos pos;
    
            Monster(int d, int index, Pos p) {
                this.distance = d;
                this.index = index;
                this.pos = p;
            }
    
            @Override
            public int compareTo(Monster o) {
                if (this.distance == o.distance) {
                    return this.pos.y - o.pos.y;
                }
                return this.distance - o.distance;
            }
        }
    }

     

     

     

     

     

     

     

     

     

    'Java > 코딩테스트' 카테고리의 다른 글

    백준 17070, 2212, 12018, 14719  (0) 2023.07.26
    코딩테스트 직전 정리  (0) 2023.07.23
    백준 20058, 프로그래머스 - 섬 연결하기, 보석쇼핑  (0) 2023.07.12
    백준 2579, 11057 - JAVA  (0) 2023.07.05
    백준 11048 - Java  (0) 2023.06.29
Designed by Tistory.