Skip to content
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

허준혁 / 11월 3주차 / 월, 목 #333

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

ComelyU
Copy link
Contributor

@ComelyU ComelyU commented Nov 13, 2023


🎈boj 25195 - Yes or yes


🗨 해결방법 :

dfs로 풀었습니다.

📝메모 :


✔코드 :

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.StringTokenizer;

/**
 * [boj] 25195. Yes or yes
 */
public class boj25195 {
    /**
     * N: 정점의 수, M: 간선의 수, S: 팬클럽 곰곰이가 존재하는 정점의 수
     */
    static int N, M, S;
    static ArrayList<Integer>[] edges;
    static HashSet<Integer> fans = new HashSet<>();
    /**
     * flag: 팬클럽 곰곰이를 만나지 않고 이동하는 방법의 존재 유무
     */
    static boolean flag;


    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");

        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());

        edges = new ArrayList[N + 1];
        for(int i = 1; i <= N; i++) {
            edges[i] = new ArrayList<>();
        }

        while(M-- > 0) {
            st = new StringTokenizer(br.readLine(), " ");

            edges[Integer.parseInt(st.nextToken())].add(Integer.parseInt(st.nextToken()));
        }

        S = Integer.parseInt(br.readLine());
        st = new StringTokenizer(br.readLine(), " ");
        while(S-- > 0) {
            fans.add(Integer.parseInt(st.nextToken()));
        }

        dfs(1);

        System.out.println(flag ? "yes" : "Yes");
    }

    public static void dfs(int nowVertex) {
        if(flag || fans.contains(nowVertex)) {
            return;
        }

        if(edges[nowVertex].isEmpty()) {
            flag = true;
            return;
        }

        for(int nextVertex: edges[nowVertex]) {
            dfs(nextVertex);
        }
    }
}


🎈boj 28449 - 누가 이길까


🗨 해결방법 :

lower bound와 upper bound로 풀었습니다.

📝메모 :


✔코드 :

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.StringTokenizer;

/**
 * [boj] 28449. 누가 이길까
 */
public class boj28449 {
    /**
     * N: HI팀의 인원 수, M: ARC팀의 인원 수
     */
    static int N, M;
    /**
     * teamHI: HI팀 참가자들의 점수, teamARC: ARC팀 참가자들의 점수
     */
    static int[] teamHI, teamARC;
    /**
     * hiWinCount: HI팀 참가자의 승리 횟수, arcWinCount: ARC팀 참가자의 승리 횟수, drawCount: 무승부 횟수
     */
    static long hiWinCount, arcWinCount, drawCount;

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        StringBuilder sb = new StringBuilder();

        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());

        teamHI = new int[N];
        st = new StringTokenizer(br.readLine(), " ");
        for(int i = 0; i < N; i++) {
            teamHI[i] = Integer.parseInt(st.nextToken());
        }
        Arrays.sort(teamHI);

        teamARC = new int[M];
        st = new StringTokenizer(br.readLine(), " ");
        for(int i = 0; i < M; i++) {
            teamARC[i] = Integer.parseInt(st.nextToken());
        }
        Arrays.sort(teamARC);


        solve();

        sb.append(hiWinCount).append(" ").append(arcWinCount).append(" ").append(drawCount).append("\n");

        System.out.print(sb.toString());
    }

    public static void solve() {
        for(int score: teamHI) {
            int lowerBoundResult = lowerBound(score);
            int upperBoundResult = upperBound(score);
            int onlySame = upperBoundResult - lowerBoundResult;

//            System.out.println(lowerBoundResult + " " + upperBoundResult);

            drawCount += onlySame;
            hiWinCount += (upperBoundResult - onlySame);
            arcWinCount += (M - upperBoundResult);
        }
    }

    /**
     * 이분 탐색 중 lower bound 이용.
     * hi팀 참가자의 점수(이하 score)를 기준으로
     * arc팀 참가자 중 score보다 같거나 큰 점수를 받은 index 반환.
     * @param score hi팀 참가자의 점수
     * @return
     */
    public static int lowerBound(int score) {
        int result = M;

        int low = 0;
        int high = M - 1;

        while(low <= high) {
            int mid = (low + high) >> 1;

            if(teamARC[mid] >= score) {
                high = mid - 1;
                result = mid;
            } else {
                low = mid + 1;
            }
        }

        return result;
    }

    /**
     * 이분 탐색 중 upper bound 이용.
     * hi팀 참가자의 점수(이하 score)를 기준으로
     * arc팀 참가자 중 score보다 큰 점수를 받은 index 반환.
     * @param score hi팀 참가자의 점수
     * @return
     */
    public static int upperBound(int score) {
        int result = M;

        int low = 0;
        int high = M - 1;

        while(low <= high) {
            int mid = (low + high) >> 1;

            if(teamARC[mid] > score) {
                high = mid - 1;
                result = mid;
            } else {
                low = mid + 1;
            }
        }

        return result;
    }
}


🎈boj 27896 - 특별한 서빙


🗨 해결방법 :

우선순위 큐로 최대 힙을 만들어 풀었습니다.

📝메모 :


✔코드 :

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

/**
 * [boj] 27896. 특별한 서빙
 */
public class boj27896 {
    /**
     * N: 학생의 수, M: 가지 운동이 일어나는 불만도의 임계점,
     * dissatisfactionSum: 불만도의 합,
     * minEggplantCnt: 가지 운동을 일으키지 않게 하기 위한 가지의 최소 개수
     */
    static int N, M, dissatisfactionSum, minEggplantCnt;
    static PriorityQueue<Integer> priorityQueue = new PriorityQueue<>((a, b) -> b - a);

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");

        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());

        st = new StringTokenizer(br.readLine(), " ");
        while(N-- > 0) {
            int dissatisfactionValue = Integer.parseInt(st.nextToken());

            priorityQueue.offer(dissatisfactionValue);
            dissatisfactionSum += dissatisfactionValue;

            while(dissatisfactionSum >= M) {
                minEggplantCnt++;
                dissatisfactionSum -= priorityQueue.poll() * 2;
            }
        }

        System.out.println(minEggplantCnt);
    }
}


🎈boj 23284 - 모든 스택 수열


🗨 해결방법 :

백트래킹으로 풀었습니다.

📝메모 :


✔코드 :

import java.io.BufferedReader;
import java.io.InputStreamReader;

/**
 * [boj] 23284. 모든 스택 수열
 */
public class boj23284 {
    static int n;
    static int[] sequence;
    static StringBuilder sb = new StringBuilder();

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        n = Integer.parseInt(br.readLine());
        sequence = new int[n];

        solve(0, 0);

        System.out.print(sb.toString());
    }

    public static void solve(int depth, int nextNum) {
        if(depth == n) {
            for(int i = 0; i < n; i++) {
                sb.append(sequence[i]).append(" ");
            }
            sb.append("\n");

            return;
        }

        for(int i = 1; i <= n; i++) { // 현재 숫자
            boolean isDuplicateNum = false;

            for(int j = 0; j < depth; j++) {
                if(sequence[j] == i) {
                    isDuplicateNum = true;
                    break;
                }
            }

            if(isDuplicateNum) {
                continue;
            }

            sequence[depth] = i;

            if(depth >= 1 && sequence[depth - 1] < sequence[depth] && sequence[depth] < nextNum) { // 이 경우 문제 조건을 만족하지 않는 수열
                break;
            }

            if(sequence[depth] >= nextNum) { // 현재 들어오는 수가 새로운 수
                solve(depth + 1, sequence[depth] + 1);
            } else { // 현재 들어오는 수가 이미 들어온 수
                solve(depth + 1, nextNum);
            }
        }
    }
}


🎈boj 1068 - 트리


🗨 해결방법 :

dfs로 풀었습니다.

📝메모 :


✔코드 :

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

/**
 * [boj] 1068. 트리
 */
public class boj1068 {
    /**
     * N: 트리의 노드 수, rootNode: 루트 노드의 번호, removeNode: 지울 노드의 번호, leafNodeCount: 리프 노드의 수
     */
    static int N, rootNode, removeNode, leafNodeCount;
    /**
     * parents: 각 노드의 부모 노드
     */
    static int[] parents;
    static boolean[] visited;

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        N = Integer.parseInt(br.readLine());

        parents = new int[N];
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        for(int i = 0; i < N; i++) {
            parents[i] = Integer.parseInt(st.nextToken());

            if(parents[i] == -1) {
                rootNode = i;
            }
        }

        removeNode = Integer.parseInt(br.readLine());

        remove(removeNode);
        visited = new boolean[N];
        countLeafNode(rootNode);

        System.out.println(leafNodeCount);
    }


    public static void remove(int removeNode) {
        parents[removeNode] = -2; // 제거한 노드의 부모 노드를 사용할 수 없는 수인 -2로 변경.

        for(int i = 0; i < N; i++) {
            if(parents[i] == removeNode) {
                remove(i);
            }
        }
    }

    public static void countLeafNode(int node) {
        visited[node] = true;
        boolean isLeafNode = true;

        if(parents[node] != -2) {
            for(int i = 0; i < N; i++) {
                if(parents[i] != node || visited[i]) {
                    continue;
                }
                countLeafNode(i);
                isLeafNode = false;
            }

            if(isLeafNode) {
                leafNodeCount++;
            }
        }
    }
}


🎈boj 2251 - 물통


🗨 해결방법 :

dfs로 풀었습니다.

📝메모 :


✔코드 :

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.util.TreeSet;

/**
 * [boj] 2251. 물통
 */
public class boj2251 {
    static int[] maxWaterOfBottles = new int[3];
    static int maxWater;
    static boolean[][] visited;
    static TreeSet<Integer> cWaters = new TreeSet<>();

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        StringBuilder sb = new StringBuilder();

        for(int i = 0; i < 3; i++) {
            maxWaterOfBottles[i] = Integer.parseInt(st.nextToken());

            if(maxWaterOfBottles[i] > maxWater) {
                maxWater = maxWaterOfBottles[i];
            }
        }
        visited = new boolean[maxWater + 1][maxWater + 1];

        dfs(0, 0, maxWaterOfBottles[2]);

        for(int water: cWaters) {
            sb.append(water).append(" ");
        }
        sb.append("\n");

        System.out.print(sb.toString());
    }

    public static void dfs(int a, int b, int c) {
        if(visited[a][b]) {
            return;
        }

        if(a == 0) {
            cWaters.add(c);
        }

        visited[a][b] = true;

        int ab = a + b;
        int ac = a + c;
        int bc = b + c;

        // a to b
        if(ab > maxWaterOfBottles[1]) {
            dfs(ab - maxWaterOfBottles[1], maxWaterOfBottles[1], c);
        } else {
            dfs(0, ab, c);
        }

        // a to c
        if(ac > maxWaterOfBottles[2]) {
            dfs(ac - maxWaterOfBottles[2], b, maxWaterOfBottles[2]);
        } else {
            dfs(0, b, ac);
        }

        // b to a
        if(ab > maxWaterOfBottles[0]) {
            dfs(maxWaterOfBottles[0], ab - maxWaterOfBottles[0], c);
        } else {
            dfs(ab, 0, c);
        }

        // b to c
        if(bc > maxWaterOfBottles[2]) {
            dfs(a, bc - maxWaterOfBottles[2], maxWaterOfBottles[2]);
        } else {
            dfs(a, 0, bc);
        }

        // c to a
        if(ac > maxWaterOfBottles[0]) {
            dfs(maxWaterOfBottles[0], b, ac - maxWaterOfBottles[0]);
        } else {
            dfs(ac, b, 0);
        }

        // c to b
        if(bc > maxWaterOfBottles[1]) {
            dfs(a, maxWaterOfBottles[1], bc - maxWaterOfBottles[1]);
        } else {
            dfs(a, bc, 0);
        }
    }
}


🎈boj 20046 - Road Reconstruction


🗨 해결방법 :

다익스트라로 풀었습니다.

📝메모 :


✔코드 :

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

/**
 * [boj] 20046. Road Reconstruction
 */
public class boj20046 {
    /**
     * m: 행, n: 열
     */
    static int m, n;
    /**
     * map: 도시를 의미하는 격자
     * 각 열의 정보는 정수 0, 1, 2, -1 로 나타내며
     * 0 은 단위도로가 이미 존재하는 것을, 즉, 도로에 유실이 없는 상태,
     * 1 은 단위 도로가 없고 1 의 비용으로 도로를 건설할 수 있는 단위 격자,
     * 2 는 단위 도로가 없고 2 의 비용으로 도로를 건설할 수 있는 단위 격자를 의미한다.
     * -1 은 X로 표시된 단위 격자로 그 위치에 단위 도로를 건설할 수 없는 상태를 의미한다.
     *
     * cost: 필요 비용
     */
    static int[][] map, cost;
    static int[] dr = {-1, 1, 0, 0}, dc = {0, 0, -1, 1};
    static final int MAX = Integer.MAX_VALUE;
    static class Vertex implements Comparable<Vertex> {
        int r;
        int c;
        int cost;

        public Vertex(int r, int c, int cost) {
            this.r = r;
            this.c = c;
            this.cost = cost;
        }

        @Override
        public int compareTo(Vertex o) {
            return Integer.compare(this.cost, o.cost);
        }
    }

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");

        m = Integer.parseInt(st.nextToken());
        n = Integer.parseInt(st.nextToken());

        map = new int[m + 1][n + 1];
        cost = new int[m + 1][n + 1];
        for(int i = 1; i <= m; i++) {
            st = new StringTokenizer(br.readLine(), " ");
            for(int j = 1; j <= n; j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
                cost[i][j] = MAX;
            }
        }

        if(map[1][1] == - 1 || map[m][n] == -1) {
            System.out.println(-1);
            return;
        }

        dijkstra();

        System.out.println(cost[m][n] == MAX ? -1 : cost[m][n]);
    }

    public static void dijkstra() {
        PriorityQueue<Vertex> pq = new PriorityQueue<>();
        pq.offer(new Vertex(1, 1, map[1][1]));

        while(!pq.isEmpty()) {
            Vertex now = pq.poll();

            if(cost[now.r][now.c] < now.cost) {
                continue;
            }

            if(now.r == m && now.c == n) {
                return;
            }

            for(int i = 0; i < 4; i++) {
                int nextR = now.r + dr[i];
                int nextC = now.c + dc[i];

                if(!isIn(nextR, nextC) || map[nextR][nextC] == -1) {
                    continue;
                }

                if(cost[nextR][nextC] > now.cost + map[nextR][nextC]) {
                    cost[nextR][nextC] = now.cost + map[nextR][nextC];

                    pq.offer(new Vertex(nextR, nextC, cost[nextR][nextC]));
                }
            }
        }
    }

    public static boolean isIn(int r, int c) {
        return 1 <= r && r <= m && 1 <= c && c <= n;
    }
}

@ComelyU ComelyU changed the title 허준혁 / 11월 3주차 / 월 허준혁 / 11월 3주차 / 월, 목 Nov 16, 2023
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