JOSEPHUS 문제입니다. 어느 케이스 부분에서 틀렸는지 모르겠어요 ㅠ

  • mju6229
    mju6229
    # define _CRT_SECURE_NO_WARNINGS
    # include <iostream>
    
    int arr[2000];
    
    int compare(const void *a,const void *b){
        return (*(int*)a - *(int*)b);
    }
    
    int main(){
        int t,i,j;
        int a,b,num,pre,L,R,C;
    
        scanf("%d",&t);
    
        for(i=0;i<t;i++){
            scanf("%d %d",&a,&b);     //a가 N    b가 K
    
            num = a-2;   //qsort 범위 정해주기위해
            pre = 1;
    
            for(j=0;j<a-1;j++){
                arr[j] = j+2;
            }
    
                arr[a-1] = 2000;
    
                for(j=0;j<a-3;j++){      //두 명 살아남을때 까지
                    qsort(arr,a,sizeof(int),compare);
    
                    R = num;
                    L=0;
                    while(L+1<=R){// 2진탐색으로 죽은사람 다음사람찾기                                //R이 죽은사람의 다음 사람
                        if(arr[num]<=pre){  //마지막 번호가 죽었을 때
                            R=0;
                            break;
                        }
                        C = (L+R)/2;
                        if(arr[C]>pre)
                            R=C;
                        else if(arr[C]<pre)
                            L=C+1;
                    }
                    if(arr[R+b-1]!=2000){   //한 바퀴 아직안돌았을 때
                        pre = arr[R+b-1];
                        arr[R+b-1]=2000;
                    }
                    else{             // 한 바퀴 돌았을 때
                        pre = arr[R+b-num-2];
                        arr[R+b-num-2]=2000;
                    }
                    num--;
                }
                qsort(arr,a,sizeof(int),compare);
                printf("%d %d\n",arr[0],arr[1]);
            }
    
        return 0;
    }
    

    조셉푸스 문제입니다. 이진탐색으로 바로 전 죽은 사람의 다음 순서를 찾아내서 다시 다음 번 죽을 사람을 찾는 방법으로 문제를 풀었습니다. 제가 생각해 볼 수 있는 예제랑 기본 예제는 답이 맞다고 하는데 제가 생각하지 못하는 부분이 무엇인지 모르겠습니다 ㅠㅠ 어느 부분에서 틀린 것인지 알 수 있을까요?

    설명을 더 하자면 기본예제 6과 3을 입력으로 받았다고 했을 때 크기 6인 배열을 받아 각 배열에 1~6까지 차례대로 입력해줍니다. 그 후 1이 죽으면 1을 100으로 바꿔주고 정렬을 시킵니다. 그리고 이전에 죽은 사람(pre)에 1을 저장해줍니다. 그러면 현재 배열엔 2 3 4 5 6 100 이 들어가 있습니다. 2~6까지 2진탐색을 돌려 1보다 큰 다음 수를 찾습니다. 2를 찾았다면 3번째 후의 차례가 죽어야 함으로 2칸을 이동한 후 결과 값인 4를 죽입니다. 그리고 똑같이 100으로 값을 변경합니다. 그 후 정렬을 하면 2 3 5 6 100 100 이 되고 pre값은 4가 됩니다. 2~6까지의 숫자를 이진탐색을 돌려 4 다음 순서를 찾습니다. 5를 찾았다면 5에서 2칸 이동 후인 2를 죽입니다. 2를 죽인 후 배열에 들어가있는 수는 3 5 6 100 100 100이 되고 pre값은 2가 됩니다. 이를 한번 더 반복하면 3 5 100 100 100 100이 되고 그러므로 값은 3과 5가 됩니다.


    7년 전
4개의 댓글이 있습니다.
  • JongMan
    JongMan

    어떻게 이진탐색을 쓰시는 건지 이해가 잘 안가네요. 예제를 덧붙여 설명해주시지 않으면 답변드리기가 어렵겠습니다. 참고로 이 문제는 이진 탐색 없이도 잘 풀립니다.


    7년 전 link
  • mju6229
    mju6229

    설명을 추가했습니다 ㅠㅠ 이진탐색을 사용하지 않고 풀어보기도 할텐데 그래도 어떤 부분이 틀린 것인지 궁금하네요.


    7년 전 link
  • JongMan
    JongMan

    음 코드가 복잡하시기 때문에 다른 방법으로 풀어보신 뒤, 랜덤한 입력을 여러 개 넣어 보시면서 틀린 답을 찾아보시는 것을 추천드립니다. orz


    7년 전 link
  • mju6229
    mju6229

    다른 방식으로 풀긴 했는데 뭔가 아쉽네요 흑 ㅠ 감사합니다 관심가져주셔서 ..


    7년 전 link
  • 정회원 권한이 있어야 커멘트를 다실 수 있습니다. 정회원이 되시려면 온라인 저지에서 5문제 이상을 푸시고, 가입 후 7일 이상이 지나셔야 합니다. 현재 문제를 푸셨습니다.