ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 9-7: 구간의 합집합
    Binary Search 2018. 10. 25. 21:43

    구간의 합집합 (union.cpp)

     

    문제


    구간은 [s, e] 로 나타내고, 이 의미는 s, (s+1), (s+2), …, (e-1), e 와 같이 숫자를 나열한 것을 의미한다. 예를 들어, [1, 4]는 1, 2, 3, 4로 숫자를 나열한 것을 의미한다. n개의 구간이 있고, 이 구간들의 숫자를 모두다 새로운 배열 S에 넣어 정렬을 한다. 이 때 S[i] 의 값이 무엇인지 출력하는 프로그램을 작성하시오. 예를 들어, 3개의 구간 [1, 3], [2, 10], [1, 8] 이 있고, S[5]를 알고싶다고 하자. 그러면 S = [1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10] 이 되고, 따라서 S[5]는 3이 된다. 배열의 인덱스는 0부터 시작한다는 것에 주의하자.

     

    입력


    첫 번째 줄에 구간의 개수 n이 주어진다 ( 1 ≤ n ≤ 10,000 ) 두 번째 줄부터 각 구간을 나타내는 숫자 s, e가 주어진다. ( 1 ≤ s ≤ e ≤ 1,000,000,000 ) 그 후, 마지막 줄에는 값을 알고 싶은 숫자의 위치 i가 주어진다. ( 1 ≤ i ≤ 10,000,000,000,000 ) i번째 위치에는 항상 숫자가 존재한다고 가정한다.  

    출력


    S[i]를 출력한다.  

    예제 입력

    2
    1 4
    3 5
    3

    예제 출력

    3

    예제 입력

    3
    1 3
    2 10
    1 8
    5

    예제 출력

    3

     


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

    public class union {

    /**
    *
    * 문제: 구간은 [s, e] 로 나타내고, 이 의미는 s, (s+1), (s+2), …, (e-1), e 와 같이 숫자를 나열한 것을 의미한다.
    * 예를 들어, [1, 4]는 1, 2, 3, 4로 숫자를 나열한 것을 의미한다. n개의 구간이 있고, 이 구간들의 숫자를 모두다 새로운 배열 S에 넣어 정렬을 한다.
    * 이 때 S[i] 의 값이 무엇인지 출력하는 프로그램을 작성하시오. 예를 들어, 3개의 구간 [1, 3], [2, 10], [1, 8] 이 있고, S[5]를 알고싶다고 하자.
    * 그러면 S = [1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10] 이 되고, 따라서 S[5]는 3이 된다. 배열의 인덱스는 0부터 시작한다는 것에 주의하자.
    *
    *
    * 입력:
    *
    * 첫 번째 줄에 구간의 개수 n이 주어진다 ( 1 ≤ n ≤ 10,000 ) 두 번째 줄부터 각 구간을 나타내는 숫자 s, e가 주어진다. ( 1 ≤ s ≤ e ≤ 1,000,000,000 )
    * 그 후, 마지막 줄에는 값을 알고 싶은 숫자의 위치 i가 주어진다. ( 1 ≤ i ≤ 10,000,000,000,000 ) i번째 위치에는 항상 숫자가 존재한다고 가정한다.
    *
    * 출력: S[i]를 출력한다.
    *
    *
    * 예제 입력:
    *
    * 2
    * 1 4
    * 3 5
    * 3
    *
    *
    * 예제 출력:
    * 3
    *
    * @param args
    */

    public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    int N = Integer.parseInt(br.readLine());
    long bounds[][] = new long[N][2];

    long max = 0, min = Long.MAX_VALUE;
    for (int i=0; i<N; i++){
    StringTokenizer st = new StringTokenizer(br.readLine(), " ");
    bounds[i][0] = Long.parseLong(st.nextToken());
    bounds[i][1] = Long.parseLong(st.nextToken());
    if (max < bounds[i][1]){
    max = bounds[i][1];
    }
    if (min > bounds[i][0]){
    min = bounds[i][0];
    }

    }

    long i = Long.parseLong(br.readLine());
    if (debug) System.out.println("targetIndex: " + i);


    long result = binarySearch(min, max, bounds, i);
    System.out.print(result);
    }

    // private static boolean debug = true;
    private static boolean debug = false;

    private static long binarySearch(long start, long end, long[][] bounds, long targetIndex){
    while (start <= end){
    if (debug) System.out.println("\nstart: " + start+ ", end: " + end);
    long mid = (start + end) /2;
    //assume mid is target number
    if (debug) System.out.println("mid: " + mid);

    //for each bound, check if bound contains mid. compute index from start.
    //find index range for element mid.

    long index = 0;
    long midContainCount = 0;


    for (int i=0; i<bounds.length; i++){
    long upper= bounds[i][1];
    long lower = bounds[i][0];
    if (debug) System.out.println("bound's lower: " + lower+ ", upper: " + upper);
    if (mid <= upper && mid>= lower){
    if (debug) System.out.println("element " + mid +" is between lower and upper, add index by " + (mid - lower));
    index+= mid - lower;
    midContainCount++;
    } else if (mid > upper){
    if (debug) System.out.println("element " + mid +" is beyond lower and upper, add index by " + (upper-lower+1));
    index+=upper-lower+1;
    }
    }

    if (debug) {
    System.out.println("index: " + index);
    System.out.println("midContainCount: " + midContainCount);
    System.out.println("index range: " + index + "~ " + (index + midContainCount-1));
    }




    if (targetIndex==index){
    if (debug) {
    System.out.println("target index equals index");
    }
    if (midContainCount !=0) return mid;
    start = mid+1;
    } else if (targetIndex > index){
    if (debug) {
    System.out.println("target index greater than index");
    }
    if (targetIndex <= (index+midContainCount-1) && midContainCount!=0) return mid;
    //else mid will have bigger value.
    start = mid +1;

    } else if (targetIndex < index){
    if (debug) {
    System.out.println("target index less than index");
    }
    end = mid - 1;

    }
    }
    return 0;
    }

    }


    'Binary Search' 카테고리의 다른 글

    9-9: 2차식 정답 추측  (0) 2018.10.25
    9-8: 숫자 개수 세기  (0) 2018.10.25
    9-5: 구슬상자  (0) 2018.10.25
    9-4: NN단표  (0) 2018.10.25
    9-2: 올라가는 달팽이  (0) 2018.10.25
Designed by Tistory.