728x90

[문제]

신종 바이러스인 웜 바이러스는 네트워크를 통해 전파된다. 한 컴퓨터가 웜 바이러스에 걸리면 그 컴퓨터와 네트워크 상에서 연결되어 있는 모든 컴퓨터는 웜 바이러스에 걸리게 된다.

예를 들어 7대의 컴퓨터가 <그림 1>과 같이 네트워크 상에서 연결되어 있다고 하자. 1번 컴퓨터가 웜 바이러스에 걸리면 웜 바이러스는 2번과 5번 컴퓨터를 거쳐 3번과 6번 컴퓨터까지 전파되어 2, 3, 5, 6 네 대의 컴퓨터는 웜 바이러스에 걸리게 된다. 하지만 4번과 7번 컴퓨터는 1번 컴퓨터와 네트워크상에서 연결되어 있지 않기 때문에 영향을 받지 않는다.

어느 날 1번 컴퓨터가 웜 바이러스에 걸렸다. 컴퓨터의 수와 네트워크 상에서 서로 연결되어 있는 정보가 주어질 때, 1번 컴퓨터를 통해 웜 바이러스에 걸리게 되는 컴퓨터의 수를 출력하는 프로그램을 작성하시오.

 

[문제 풀이]

이 문제는 BFS 또는 DFS를 이용하여 해결 할 수 있다.

그리고 BFS와 DFS를 구현하는데 matrix 또는 list로 구현이 가능한데 두 가지 방법으로 다 풀어보았다.

 

1. BFS Linked list

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {
    static int N, M;
    static Queue<Integer> q = new LinkedList<>();
    static boolean[] visited;
    static Node[] adj;

    static int stoi(String s) {
        return Integer.parseInt(s);
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = stoi(br.readLine());
        M = stoi(br.readLine());

        visited = new boolean[N+1];
        adj = new Node[N+1];

        for (int i=0; i<M; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            int u = stoi(st.nextToken());
            int v = stoi(st.nextToken());

            adj[u] = new Node(v, adj[u]);
            adj[v] = new Node(u, adj[v]);
        }

        System.out.println(bfs(1));
    }

    public static int bfs(int n) {
        int cnt = 0;
        visited[n] = true;
        q.offer(n);

        while(!q.isEmpty()) {
            int x = q.poll();

            for (Node node=adj[x]; node!=null; node=node.next) {
                if (!visited[node.n]) {
                    q.offer(node.n);
                    visited[node.n] = true;
                    cnt++;
                }
            }
        }

        return cnt;
    }

    static class Node {
        int n;
        Node next;

        public Node(int n, Node next) {
            this.n = n;
            this.next = next;
        }
    }
}

2. DFS Linked list

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

public class Main {
    static int n, m;
    static Node[] adj;
    static boolean[] visit;
    static int cnt;

    public static int stoi(String s) {
        return Integer.parseInt(s);
    }

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

        n = stoi(br.readLine());
        m = stoi(br.readLine());

        adj = new Node[n+1];
        visit = new boolean[n+1];
        for (int i=0; i<m; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            int u = stoi(st.nextToken());
            int v = stoi(st.nextToken());

            adj[u] = new Node(v, adj[u]);
            adj[v] = new Node(u, adj[v]);
        }

        dfs(1);
        System.out.println(cnt);
    }

    public static void dfs(int v) {
        visit[v] = true;

        for (Node node=adj[v]; node!=null; node=node.next) {
            if (!visit[node.n]) {
                cnt++;
                dfs(node.n);
            }
        }
    }

    static class Node {
        int n;
        Node next;

        public Node(int n, Node next) {
            this.n = n;
            this.next = next;
        }
    }
}

3. DFS Matrix

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

public class Main {
    static int n, m;
    static int[][] matrix;
    static boolean[] visit;
    static int cnt;

    public static int stoi(String s) {
        return Integer.parseInt(s);
    }

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

        n = stoi(br.readLine());
        m = stoi(br.readLine());

        matrix = new int[n+1][n+1];
        visit = new boolean[n+1];
        for (int i=0; i<m; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            int u = stoi(st.nextToken());
            int v = stoi(st.nextToken());

            matrix[u][v] = 1;
            matrix[v][u] = 1;
        }

        dfs(1);
        System.out.println(cnt);
    }

    public static void dfs(int v) {
        visit[v] = true;

        for (int i=1; i<=n; i++) {
            if (matrix[v][i]==1 && !visit[i]) {
                cnt++;
                dfs(i);
            }
        }
    }
}

[결과]

BFS - list

DFS - list

DFS - matrix

순으로 결과는 다음과 같이 나왔다.

728x90

'Algorithm > Baekjoon' 카테고리의 다른 글

[BOJ] 1991 트리 순회 - Java  (0) 2021.07.16
[BOJ] 5639 이진 검색 트리 - Java  (0) 2021.07.16
[BOJ] 1068 트리 - Java  (0) 2021.07.14
[BOJ] 11279 최대 힙 - Java  (0) 2021.07.14
[BOJ] 1927 최소 힙 - Java  (0) 2021.07.14
728x90

[문제]

이진 트리를 입력받아 전위 순회(preorder traversal), 중위 순회(inorder traversal), 후위 순회(postorder traversal)한 결과를 출력하는 프로그램을 작성하시오.

예를 들어 위와 같은 이진 트리가 입력되면,

  • 전위 순회한 결과 : ABDCEFG // (루트) (왼쪽 자식) (오른쪽 자식)
  • 중위 순회한 결과 : DBAECFG // (왼쪽 자식) (루트) (오른쪽 자식)
  • 후위 순회한 결과 : DBEGFCA // (왼쪽 자식) (오른쪽 자식) (루트)

가 된다.

[문제 풀이]

배열과 해쉬맵 두가지 방법으로 입력을 받아서 문제를 해결하였다.

먼저 입력 받은 N 크기 만큼 노드를 만들었다.

노드가 왼쪽, 오른쪽 자식이 있다면 아래 코드와 같이 넣어주었다.

루트부터 시작해서 전위, 중위, 후위 순위를 아래  코드와 같이 돌려주었다.

 

[코드 - 배열]

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

public class Main {

    static int N;
    static Node[] arr;
    static StringBuilder sb = new StringBuilder();

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());
        arr = new Node[N];
        for (int i=0; i<N; i++) {
            arr[i] = new Node((char)(i + 'A'));
        }

        for (int i=0; i<N; i++) {
            char n, l, r;
            String s = br.readLine();
            n = s.charAt(0);
            l = s.charAt(2);
            r = s.charAt(4);
            if (l != '.') {
                arr[n-'A'].left = arr[l-'A'];
            }
            if (r != '.'){
                arr[n-'A'].right = arr[r-'A'];
            }
        }

        // 전위 순회
        preOrder(arr[0]);
        sb.append("\n");
        // 중위 순회
        inOrder(arr[0]);
        sb.append("\n");
        // 후위 순회
        postOrder(arr[0]);
        sb.append("\n");

        System.out.println(sb);
    }

    static void preOrder(Node node) {
        sb.append(node.ch);
        if (node.left != null) preOrder(node.left);
        if (node.right != null) preOrder(node.right);
    }

    static void inOrder(Node node) {
        if (node.left != null) inOrder(node.left);
        sb.append(node.ch);
        if (node.right != null) inOrder(node.right);
    }

    static void postOrder(Node node) {
        if (node.left != null) postOrder(node.left);
        if (node.right != null) postOrder(node.right);
        sb.append(node.ch);
    }

    static class Node {
        char ch;
        Node left;
        Node right;

        public Node(char ch) {
            this.ch = ch;
        }
    }
}

 

[코드 - 해쉬 맵]

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

public class Main {

    static int N;
    static Map<Character, Node> map = new HashMap<>();
    static StringBuilder sb = new StringBuilder();

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());
        for (int i=0; i<N; i++) {
            map.put((char)('A'+i), new Node((char)('A'+i)));
        }

        for (int i=0; i<N; i++) {
            char n, l, r;
            String s = br.readLine();
            n = s.charAt(0);
            l = s.charAt(2);
            r = s.charAt(4);
            if (l != '.') {
                map.get(n).left = map.get(l);
            }
            if (r != '.'){
                map.get(n).right = map.get(r);
            }
        }

        // 전위 순회
        preOrder(map.get('A'));
        sb.append("\n");
        // 중위 순회
        inOrder(map.get('A'));
        sb.append("\n");
        // 후위 순회
        postOrder(map.get('A'));
        sb.append("\n");

        System.out.println(sb);
    }

    static void preOrder(Node node) {
        sb.append(node.ch);
        if (node.left != null) preOrder(node.left);
        if (node.right != null) preOrder(node.right);
    }

    static void inOrder(Node node) {
        if (node.left != null) inOrder(node.left);
        sb.append(node.ch);
        if (node.right != null) inOrder(node.right);
    }

    static void postOrder(Node node) {
        if (node.left != null) postOrder(node.left);
        if (node.right != null) postOrder(node.right);
        sb.append(node.ch);
    }

    static class Node {
        char ch;
        Node left;
        Node right;

        public Node(char ch) {
            this.ch = ch;
        }
    }
}

[실행 결과 - 배열]

[실행 결과 - 해쉬 맵]

실행 결과는 위와 같다.

728x90

'Algorithm > Baekjoon' 카테고리의 다른 글

[BOJ] 2606 바이러스 - Java  (0) 2021.07.26
[BOJ] 5639 이진 검색 트리 - Java  (0) 2021.07.16
[BOJ] 1068 트리 - Java  (0) 2021.07.14
[BOJ] 11279 최대 힙 - Java  (0) 2021.07.14
[BOJ] 1927 최소 힙 - Java  (0) 2021.07.14
728x90

[문제]

이진 검색 트리는 다음과 같은 세 가지 조건을 만족하는 이진 트리이다.

  • 노드의 왼쪽 서브트리에 있는 모든 노드의 키는 노드의 키보다 작다.
  • 노드의 오른쪽 서브트리에 있는 모든 노드의 키는 노드의 키보다 크다.
  • 왼쪽, 오른쪽 서브트리도 이진 검색 트리이다.

전위 순회 (루트-왼쪽-오른쪽)은 루트를 방문하고, 왼쪽 서브트리, 오른쪽 서브 트리를 순서대로 방문하면서 노드의 키를 출력한다. 후위 순회 (왼쪽-오른쪽-루트)는 왼쪽 서브트리, 오른쪽 서브트리, 루트 노드 순서대로 키를 출력한다. 예를 들어, 위의 이진 검색 트리의 전위 순회 결과는 50 30 24 5 28 45 98 52 60 이고, 후위 순회 결과는 5 28 24 45 30 60 52 98 50 이다.

이진 검색 트리를 전위 순회한 결과가 주어졌을 때, 이 트리를 후위 순회한 결과를 구하는 프로그램을 작성하시오.

 

[문제 풀이]

전위 순회 (루트, 왼쪽, 오른쪽) 로 입력이 들어올때 노드를 생성하며 tree 구조로 만들어 주었다.

만들어진 tree 구조에서 후위 순회를 하며 결과를 하나씩 출력해 주었다.

 

 

[코드]

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

public class Main {

    static Node root;
    static StringBuilder sb = new StringBuilder();

    static int stoi(String s) {
        return Integer.parseInt(s);
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        root = new Node(stoi(br.readLine()));

        // 노드 생성 트리 생성
        String n;
        while(true) {
            n = br.readLine();
            if (n == null || n.equals("")) break;
            Node node = new Node(stoi(n));
            connectNode(root, node);
        }

        // 후위 순회
        postOrder(root);
        System.out.println(sb);
    }

    static void postOrder(Node node) {
        if (node.left != null) postOrder(node.left);
        if (node.right != null) postOrder(node.right);
        sb.append(node.num).append("\n");
    }

    static void connectNode(Node cur, Node next) {
        if (next.num < cur.num) {
            if (cur.left != null) {
                connectNode(cur.left, next);
            } else {
                cur.left = next;
            }
        } else {
            if (cur.right != null) {
                connectNode(cur.right, next);
            } else {
                cur.right = next;
            }
        }
    }

    static class Node {
        int num;
        Node left;
        Node right;

        Node(int num) {
            this.num = num;
        }
    }
}

[실행 결과]

이와 같이 나온다.

728x90

'Algorithm > Baekjoon' 카테고리의 다른 글

[BOJ] 2606 바이러스 - Java  (0) 2021.07.26
[BOJ] 1991 트리 순회 - Java  (0) 2021.07.16
[BOJ] 1068 트리 - Java  (0) 2021.07.14
[BOJ] 11279 최대 힙 - Java  (0) 2021.07.14
[BOJ] 1927 최소 힙 - Java  (0) 2021.07.14
728x90

[문제]

트리에서 리프 노드란, 자식의 개수가 0인 노드를 말한다.

트리가 주어졌을 때, 노드 하나를 지울 것이다. 그 때, 남은 트리에서 리프 노드의 개수를 구하는 프로그램을 작성하시오. 노드를 지우면 그 노드와 노드의 모든 자손이 트리에서 제거된다.

예를 들어, 다음과 같은 트리가 있다고 하자.

현재 리프 노드의 개수는 3개이다. (초록색 색칠된 노드) 이때, 1번을 지우면, 다음과 같이 변한다. 검정색으로 색칠된 노드가 트리에서 제거된 노드이다.

이제 리프 노드의 개수는 1개이다.

[문제 풀이]

제거할 노드를 부모로 가지고 있는 모든 노드들을 제거하기 위해 BFS를 사용했다.

delete(int node) 함수는 bfs를 구현한 것으로 (제거할 노드 == 부모 노드) 일때 큐에 넣어주고 하나씩 꺼내면서 제거해 주었다.

제거하면서 boolean 변수 visited=true로 방문체크를 하였다.

이후 leaf 노드를 찾기 위해 방문을 안한 노드를 찾아가면서 노드가 가리키는 숫자는 부모노드이므로 그 숫자들을 방문 체크하였다.

결국 하나도 방문하지 않은 노드가 leaf 노드가 된다.

방문하지 않는 노드 수를 세서 출력해주면 leaf 노드의 수가 나온다.

 

[코드]

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {

    static int N;
    static int[] parents;
    static int removeNode;
    static boolean[] visited;
    static boolean[] leaves;

    static int stoi(String s) {
        return Integer.parseInt(s);
    }

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

        parents = new int[N];
        visited = new boolean[N];
        leaves  = new boolean[N];
        Arrays.fill(leaves, true);

        StringTokenizer st = new StringTokenizer(br.readLine());
        for (int i=0; i<N; i++) {
            parents[i] = stoi(st.nextToken());
        }

        removeNode = stoi(br.readLine());
        if (parents[removeNode] == -1) {
            System.out.println(0);
            return;
        }

        delete(removeNode);

        for (int i=0; i<N; i++) {
            if (parents[i] == -1) continue;
            if (!visited[i]) {
                leaves[parents[i]] = false;
            }
        }
        
        int ans = 0;
        for (int i=0; i<N; i++) {
            if (leaves[i]) ans++;
        }
        System.out.println(ans);
    }

    static void delete(int node) {
        visited[node] = true;
        leaves[node] = false;

        Queue<Integer> queue = new LinkedList<>();
        queue.add(node);

        while(!queue.isEmpty()) {
            int cur = queue.poll();
            for (int i=0; i<N; i++) {
                if (cur == parents[i] && !visited[i]) {
                    visited[i] = true;
                    leaves[i] = false;
                    queue.offer(i);
                }
            }
        }
    }
}

[실행 결과]

실행 결과는 위와 같다.

728x90

'Algorithm > Baekjoon' 카테고리의 다른 글

[BOJ] 1991 트리 순회 - Java  (0) 2021.07.16
[BOJ] 5639 이진 검색 트리 - Java  (0) 2021.07.16
[BOJ] 11279 최대 힙 - Java  (0) 2021.07.14
[BOJ] 1927 최소 힙 - Java  (0) 2021.07.14
[BOJ] 2110 공유기 설치 - Java  (0) 2021.07.14
728x90

[문제]

널리 잘 알려진 자료구조 중 최대 힙이 있다. 최대 힙을 이용하여 다음과 같은 연산을 지원하는 프로그램을 작성하시오.

  1. 배열에 자연수 x를 넣는다.
  2. 배열에서 가장 큰 값을 출력하고, 그 값을 배열에서 제거한다.

프로그램은 처음에 비어있는 배열에서 시작하게 된다.

[문제 풀이]

이 문제는 이전 최소 힙 문제 풀이와 유사하다.

PriorityQueue에 넣을 때 -1을 곱해서 넣어주고

뺄 때 다시 -1을 곱한 값을 출력해 주면 된다.

참고: https://dos-soles.tistory.com/11?category=873473

 

[코드]

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

public class Main {

    static int N;
    static PriorityQueue<Integer> queue = new PriorityQueue<>();

    static int stoi(String s) {
        return Integer.parseInt(s);
    }

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

        N = stoi(br.readLine());
        for (int i=0; i<N; i++) {
            int x = stoi(br.readLine());

            if (x == 0) {
                if (queue.isEmpty()) sb.append(0).append("\n");
                else {
                    sb.append(queue.poll()*-1).append("\n");
                }
            } else {
                queue.offer(x*-1);
            }
        }
        System.out.println(sb);
    }
}

[실행 결과]

실행 결과는 위와 같다.

728x90

'Algorithm > Baekjoon' 카테고리의 다른 글

[BOJ] 5639 이진 검색 트리 - Java  (0) 2021.07.16
[BOJ] 1068 트리 - Java  (0) 2021.07.14
[BOJ] 1927 최소 힙 - Java  (0) 2021.07.14
[BOJ] 2110 공유기 설치 - Java  (0) 2021.07.14
[BOJ] 1654 랜선 자르기 - Java  (0) 2021.07.14
728x90

[문제]

널리 잘 알려진 자료구조 중 최소 힙이 있다. 최소 힙을 이용하여 다음과 같은 연산을 지원하는 프로그램을 작성하시오.

  1. 배열에 자연수 x를 넣는다.
  2. 배열에서 가장 작은 값을 출력하고, 그 값을 배열에서 제거한다.

프로그램은 처음에 비어있는 배열에서 시작하게 된다.

[문제 풀이]

우선순위 큐는 힙으로 구현되면 위 문제는 우선순위 큐로 규현해야 하는 문제이다.

자바에서 우선순위 큐는 PriorityQueue로 구현 할 수 있다.

기본으로 최소힙으로 구현되어 있기 때문에 문제에서 0이 입력 받을 때마다 queue가 비어 있지 않다면 그냥 출력해 주면 되는 문제이다.

 

[코드]

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

public class Main {

    static int N;
    static PriorityQueue<Integer> queue = new PriorityQueue<>();

    static int stoi(String s) {
        return Integer.parseInt(s);
    }

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

        N = stoi(br.readLine());

        for (int i=0; i<N; i++) {
            int x = stoi(br.readLine());

            if (x==0) {
                if (queue.isEmpty()) sb.append(0).append("\n");
                else {
                    sb.append(queue.poll()).append("\n");
                }
            } else {
                queue.offer(x);
            }
        }

        System.out.println(sb);
    }
}

[실행 결과]

실행 결과는 위와 같다.

728x90

'Algorithm > Baekjoon' 카테고리의 다른 글

[BOJ] 1068 트리 - Java  (0) 2021.07.14
[BOJ] 11279 최대 힙 - Java  (0) 2021.07.14
[BOJ] 2110 공유기 설치 - Java  (0) 2021.07.14
[BOJ] 1654 랜선 자르기 - Java  (0) 2021.07.14
[BOJ] 1931 회의실 배정 - Java  (0) 2021.07.14
728x90

[문제]

도현이의 집 N개가 수직선 위에 있다. 각각의 집의 좌표는 x1, ..., xN이고, 집 여러개가 같은 좌표를 가지는 일은 없다.

도현이는 언제 어디서나 와이파이를 즐기기 위해서 집에 공유기 C개를 설치하려고 한다. 최대한 많은 곳에서 와이파이를 사용하려고 하기 때문에, 한 집에는 공유기를 하나만 설치할 수 있고, 가장 인접한 두 공유기 사이의 거리를 가능한 크게 하여 설치하려고 한다.

C개의 공유기를 N개의 집에 적당히 설치해서, 가장 인접한 두 공유기 사이의 거리를 최대로 하는 프로그램을 작성하시오.

[문제 풀이]

우선 집의 좌표를 배열에 다 넣어주고 오름차순으로 정렬한다.

이분 탐색을 이용해서 두 공유기 사이의 최대 거리를 찾아줄 것이다.

가능한 범위는 1 부터  마지막 집과 첫 집 사이의 거리이므로

s = 1, e = arr[N-1] - arr[0]으로 초기화 시켜주었다.

그 다음 m = (s+e)/2 가 된다.

공유기 설치한 마지막 집을 left라고 두자.

left와 다음 집 사이의 거리가 m 보다 크면 공유기를 설치할 수 있으므로 cnt를 증가시키고 left = arr[i] 가 된다.

공유기 설치가 끝나면 문제에서 주어진 c개인지 확인해야한다.

공유기를 설치한 cnt 값이 c보다 많거나 작다면 m을 늘려주어야 하므로

ans = m, s = m+1로 만들어준다.

c보다 크면 m을 줄여주어야 한다. 따라서 e = m-1이 된다.

다 돌면 ans를 출력해 주면 된다.

 

 

[코드]

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

public class Main {
	
	static int N, C;
	static int[] arr;
	
	static int stoi(String s) {
		return Integer.parseInt(s);
	}
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		
		N = stoi(st.nextToken());
		C = stoi(st.nextToken());
		arr = new int[N];
		
		for (int i=0; i<N; i++) {
			arr[i] = stoi(br.readLine());
		}
		Arrays.sort(arr);
		
		int ans = 0;
		
		int s = 1;
		int e = arr[N-1] - arr[0];
		while (s <= e) {
			int m = (s + e) / 2;	// 거리
			int left = arr[0];		// 이전 공유기 설치한 집
			int cnt = 1;			// 공유기 설치한 갯수
			
			for (int i=1; i<N; i++) {
				// 차이가 m 보다 크면 설치 가능
				if (arr[i] - left >= m) {
					cnt++;
					left = arr[i];
				}
			}
			// 공유기 설치 끝
			
			// 설치한 공유기가 C보다 많거나 같으면 줄여야함
			if (C <= cnt) {
				ans = m;
				s = m + 1;
			} else {	// 설치한 공유기가 부족하면 늘려야 함
				e = m - 1;
			}
		}
		System.out.println(ans);
	}
}

[실행 결과]

결과는 위와 같다.

728x90

'Algorithm > Baekjoon' 카테고리의 다른 글

[BOJ] 11279 최대 힙 - Java  (0) 2021.07.14
[BOJ] 1927 최소 힙 - Java  (0) 2021.07.14
[BOJ] 1654 랜선 자르기 - Java  (0) 2021.07.14
[BOJ] 1931 회의실 배정 - Java  (0) 2021.07.14
[BOJ] 11399 ATM - Java  (0) 2021.07.14
728x90

[문제]

집에서 시간을 보내던 오영식은 박성원의 부름을 받고 급히 달려왔다. 박성원이 캠프 때 쓸 N개의 랜선을 만들어야 하는데 너무 바빠서 영식이에게 도움을 청했다.

이미 오영식은 자체적으로 K개의 랜선을 가지고 있다. 그러나 K개의 랜선은 길이가 제각각이다. 박성원은 랜선을 모두 N개의 같은 길이의 랜선으로 만들고 싶었기 때문에 K개의 랜선을 잘라서 만들어야 한다. 예를 들어 300cm 짜리 랜선에서 140cm 짜리 랜선을 두 개 잘라내면 20cm는 버려야 한다. (이미 자른 랜선은 붙일 수 없다.)

편의를 위해 랜선을 자르거나 만들 때 손실되는 길이는 없다고 가정하며, 기존의 K개의 랜선으로 N개의 랜선을 만들 수 없는 경우는 없다고 가정하자. 그리고 자를 때는 항상 센티미터 단위로 정수길이만큼 자른다고 가정하자. N개보다 많이 만드는 것도 N개를 만드는 것에 포함된다. 이때 만들 수 있는 최대 랜선의 길이를 구하는 프로그램을 작성하시오.

[문제 풀이]

이 문제는 이분탐색을 이용해야하는 문제이다. 이분탐색하지 않으면 시간초과가 난다.

시작 s 는 1 마지막 e는 가장긴 랜선으로 두면 가운데 m 값은 (s+e)/2 이다.

이 m 값이 만들 전선의 길이가 된다.

이 전선의 길이로는 갯수가 부족하면 m을 줄여주어야 하므로 e = m-1이 되고

갯수가 많거나 같으면 s = m+1로 두면

결국에는 마지막 e 값이 주어진 n개를 만들 수 있는 랜선의 최대 길이가 된다.

e 를 출력해 주면 된다.

 

[코드]

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

public class Main {
	
	static int K, N;
	static int[] wires;
	
	static int stoi(String s) {
		return Integer.parseInt(s);
	}
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		
		K = stoi(st.nextToken());
		N = stoi(st.nextToken());
		
		wires = new int[K];
		for (int i=0; i<K; i++) {
			wires[i] = stoi(br.readLine());
		}
		Arrays.sort(wires);
		
		long s = 1;
		long e = wires[K-1];
        
		while (s <= e) {
			long cnt = 0;
			long m = (s + e) / 2;
			
			for (int i=0; i<K; i++) {
				cnt += wires[i] / m;
			}
			
			if (N > cnt) {
				e = m - 1;
			} else {
				s = m + 1;
			}
		}
		System.out.println(e);
	}
}

[실행 결과]

실행 결과는 위와 같다.

728x90

'Algorithm > Baekjoon' 카테고리의 다른 글

[BOJ] 1927 최소 힙 - Java  (0) 2021.07.14
[BOJ] 2110 공유기 설치 - Java  (0) 2021.07.14
[BOJ] 1931 회의실 배정 - Java  (0) 2021.07.14
[BOJ] 11399 ATM - Java  (0) 2021.07.14
[BOJ] 10799 쇠막대기 - Java  (0) 2021.07.14

+ Recent posts