알고리즘/[ Baekjoon ]

[ BOJ ][JAVA][2352] 반도체 설계

kim.svadoz 2021. 4. 22. 23:55
반응형

www.acmicpc.net/problem/2352

 

2352번: 반도체 설계

첫째 줄에 정수 n(1 ≤ n ≤ 40,000)이 주어진다. 다음 줄에는 차례로 1번 포트와 연결되어야 하는 포트 번호, 2번 포트와 연결되어야 하는 포트 번호, …, n번 포트와 연결되어야 하는 포트 번호가 주

www.acmicpc.net

시간 제한 메모리 제한 제출 정답 맞은 사람 정답 비율
2 초 128 MB 8696 3378 2574 43.421%

문제

반도체를 설계할 때 n개의 포트를 다른 n개의 포트와 연결해야 할 때가 있다.

img

예를 들어 왼쪽 그림이 n개의 포트와 다른 n개의 포트를 어떻게 연결해야 하는지를 나타낸다. 하지만 이와 같이 연결을 할 경우에는 연결선이 서로 꼬이기 때문에 이와 같이 연결할 수 없다. n개의 포트가 다른 n개의 포트와 어떻게 연결되어야 하는지가 주어졌을 때, 연결선이 서로 꼬이지(겹치지, 교차하지) 않도록 하면서 최대 몇 개까지 연결할 수 있는지를 알아내는 프로그램을 작성하시오

입력

첫째 줄에 정수 n(1 ≤ n ≤ 40,000)이 주어진다. 다음 줄에는 차례로 1번 포트와 연결되어야 하는 포트 번호, 2번 포트와 연결되어야 하는 포트 번호, …, n번 포트와 연결되어야 하는 포트 번호가 주어진다. 이 수들은 1 이상 n 이하이며 서로 같은 수는 없다고 가정하자.

출력

첫째 줄에 최대 연결 개수를 출력한다.

예제 입력 1

6
4 2 6 3 1 5

예제 출력 1

3

코드

/*
실제 binarySearch 메소드 -> 를 활용하는게 직접 구현하는것보다 시간효율이 조금 더 좋다
    public static int binarySearch(int[] a, int fromIndex, int toIndex, int key) {
        rangeCheck(a.length, fromIndex, toIndex);
        return binarySearch0(a, fromIndex, toIndex, key);
    }
// Like public version, but without range checks.
    private static int binarySearch0(int[] a, int fromIndex, int toIndex, int key) {
        int low = fromIndex;
        int high = toIndex - 1;
        while (low <= high) {
            int mid = (low + high) >>> 1;
            int midVal = a[mid];
            if (midVal < key)
                low = mid + 1;
            else if (midVal > key)
                high = mid - 1;
            else
                return mid; // key found
        }
        return -(low + 1); // key not found.
    }
*/
import java.io.*;
import java.util.*;
public class p2352 {
    static int n, arr[], lis[];
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        n = Integer.parseInt(br.readLine());
        arr = new int[n + 1];
        lis = new int[n + 1];
        StringTokenizer st = new StringTokenizer(br.readLine());
        for (int i = 1; i < n + 1; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
        }

        lis[1] = arr[1];
        int lis_cnt = 0;
        for (int i = 1; i <= n; i++) {
            if (i == 1 || arr[i] > lis[lis_cnt - 1]) {
                lis[lis_cnt++] = arr[i];
            } else {
                int left = 0, right = lis_cnt;
                int idx = lis_cnt;
                while (left < right) {
                    int mid = (left + right) / 2;
                    if (lis[mid] >= arr[i]) {
                        idx = Math.min(idx, mid);
                        right = mid;
                    } else {
                        left = mid + 1;
                    }
                }
                lis[idx] = arr[i];
            }
        }

        System.out.println(lis_cnt);
    }
}

/***************************** Arrays.binarySearch() 메소드 사용 코드 ***********************
import java.io.*;
import java.util.*;
public class Main {
    static int n, arr[], lis[];
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        n = Integer.parseInt(br.readLine());
        arr = new int[n];
        lis = new int[n];
        StringTokenizer st = new StringTokenizer(br.readLine());
        for (int i = 0; i < n; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
        }
        int lis_cnt = 0;
        for (int i = 0; i < n; i++) {
            if (i == 0 || arr[i] > lis[lis_cnt - 1]) {
                lis[lis_cnt++] = arr[i];
            } else {
                int idx = Arrays.binarySearch(lis, 0, lis_cnt, arr[i]);
                idx = (idx < 0) ? -idx -1 : idx;
                lis[idx] = arr[i];
            }
        }

        System.out.println(lis_cnt);
    }
}
*/
반응형