ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 08. 8차시 수업
    알고리즘/정올1차교육(17.7.12~17.8.14) 2017. 8. 2. 21:27
    반응형

    01.cpp - 회전초밥

    *제가 짠 소스가 아닙니다*

    /*
    #include <stdio.h>

    #define MAX_DISH 3000001
    #define MAX_FISH 3001

    int dishes[MAX_DISH];
    int hash[MAX_FISH];

    int head_idx = 0, tail_idx = 0;

    int safe_increment(const unsigned int index, const unsigned int dish){
    //dishes에 필요한 인덱스가 범위를 넘어가지 않도록 한다
    return (index + 1) % dish;
    }

    int enqueue(const unsigned int current_num, const unsigned int dish){
    const unsigned int ret =
    (++hash[dishes[head_idx]] == 1) ? (current_num + 1) : (current_num);
    head_idx = safe_increment(head_idx, dish);
    return ret;
    }

    int dequeue(const unsigned int current_num, const unsigned int dish){
    const unsigned int ret =
    (--hash[dishes[tail_idx]] == 0) ? (current_num - 1) : (current_num);
    tail_idx = safe_increment(tail_idx, dish);
    return ret;
    }

    int main(){
    int n_dish, n_fish, k, coupon;
    int i, max = 1; //1은 최초에 쿠폰으로 1개 먹기 때문
    int enq = 0;

    scanf("%d %d %d %d", &n_dish, &n_fish, &k, &coupon);

    for(i = 0; i < n_dish; ++i){
    scanf("%d", &dishes[i]);
    }

    hash[coupon]++;

    for(i = 0; i < k; ++i){
    enq = enqueue(max, n_dish);
    max = (enq > max) ? enq : max ;
    }

    for(i = 0; i < n_dish - 1; ++i){
    int j;
    enq = enqueue(dequeue(enq, n_dish), n_dish);

    max = (enq > max) ? enq : max;
    }

    printf("%d", max);

    }
    */



    02.cpp - binary search. 이진탐색


    //binary search
    #include <stdio.h>
    #include <algorithm>
    using namespace std;
    int first, last;
    int arr[100001];
    int original[100001];
    int want_to_find;
    int N;
    int binary_search(){
    if(last<first) return -1;
    int middle=(last+first+1)/2;
    if(want_to_find==arr[middle]) return middle;
    else if(want_to_find<arr[middle]) last=middle-1;
    else first=middle+1;
    return binary_search();
    }
    int main(){
    scanf("%d", &N);
    last=N;
    int cnt=1;
    for(int i=1; i<=N; ++i){
    scanf("%d", &arr[i]);
    original[arr[i]]=cnt++;
    }
    puts("want to find(it need not to be sorted)");
    scanf("%d", &want_to_find);
    sort(arr, arr+N);
    printf("that's on %d index(starts from zero)", original[binary_search()]);
    }

    이진탐색입니다. 항상 정렬된 배열 기준으로 first부터 last까지의 값 중 중간값((first+last+1)/2)을 구해서 그 값이 want_to_find와 같으면 그 인덱스를 리턴, 그 중간값이 want_to_find보다 작으면 first를 중간값+1로 옮기고 그 반대면 last를 중간값-1로 옮긴 후 재귀 돌립니다.

    숫자 맞추기 게임(up&down게임)의 공략이기도 한 이진탐색입니다.

    선생님 : 숫자 1부터 100까지 중 내가 뭘생각하고있게? 숫자 말하면 그 숫자가 내가 생각한 숫자보다 높은지 낮은지만 알려줄게!

    총 7번만 말하면 찾을 수 있겠죠



    03.cpp - Lis algorithm <ver.1 : find temp's length>

    //longest increasing subsequence
    //ver.1
    #include <stdio.h>
    int arr[100000];
    int temp[100000];
    int t_last=0;
    int first=0, last;
    int N;

    int upgraded_b_search(int target, int range_f, int range_l){
    if(range_f==range_l) return range_l;
    else if(range_f+1==range_l){
    return range_l;
    }
    int middle=(first+last+1)/2;
    if(temp[middle]==target) return middle;
    else if(temp[middle]>target){
    range_l=middle;
    last=middle-1;
    }
    else{
    range_f=middle;
    first=middle+1;
    }
    return upgraded_b_search(target, range_f, range_l);
    }

    void find_Lis_length(){
    for(int i=1; i<N; ++i){
    first=0;
    last=t_last;
    if(arr[i]>temp[t_last]){
    temp[++t_last]=arr[i];
    //printf("okay\n");
    }
    else{
    //printf("b_search : ");
    int d=upgraded_b_search(arr[i], 0, t_last);
    //printf("upgraded_b_search(arr[i], 0, t_last) : %d\n",d);
    temp[d]=arr[i];
    }
    //for(int i=0; i<t_last; ++i){
    // printf("%d ", temp[i]);
    //}
    //printf("\n");
    }
    return;
    }

    int main(){
    scanf("%d", &N);
    for(int i=0; i<N; ++i){
    scanf("%d", &arr[i]);
    }
    temp[0]=arr[0];
    find_Lis_length();
    printf("\n");
    for(int i=0; i<t_last+1; ++i){
    printf("%d ", temp[i]);
    }
    printf("\n");
    printf("length : %d", t_last+1);//index starts from zero. so +1.

    }

    LIS알고리즘 중 binary-search를 이용해서 temp의 길이를 구하는 코드입니다.

    원래는 lower-bound를 이용해서 푸는게 정석이지만 lower-bound까지 구현하고 싶어서 이렇게 짜봤습니다.

    우선 결론 : lower-bound씁시다


    그럼 이제 설명하겠습니다.

    <temp배열을 만드는 방법>

    1. 준비물 : arr배열, binary-search 함수 등등

    2. 로직을 설명드리겠습니다.

    (1) temp[0]에 arr[0]을 대입합니다.

    (2) arr[1]부터 arr[n]까지 temp의 가장 마지막 숫자와 비교합니다.

    arr[i]가 temp[last]보다 크면 ++last에 arr[i]를 대입합니다.

    그 반대면 temp에서 arr[i]보다 큰 최소의 수를 binaray search(이진탐색)을 이용해서 찾습니다. 그리고 그 수에 arr[i]를 대입합니다. 이때 last는 변하지 않습니다.

    (3) 배열의 길이는 last+1입니다. (배열이 0부터 시작하기 때문에)

    LIS에 대한 자세한 설명은 다음시간에 하겠습니다.

    반응형

    '알고리즘 > 정올1차교육(17.7.12~17.8.14)' 카테고리의 다른 글

    10. 10차시 수업  (0) 2017.08.07
    09. 9차시 수업  (0) 2017.08.06
    07. 7차시 수업  (0) 2017.07.31
    06. 6차시 수업  (0) 2017.07.30
    05. 5차시 수업  (0) 2017.07.27

    댓글

Designed by Tistory.