[해결완료] FIRE(봉화대 설치) 문제 오답 TC를 못찾고 있습니다.. 이런경우 어떤식으로 해결을 해야할까요?

  • gloryof11
    gloryof11

    안녕하세요!

    도움을 주셔서 시간초과는 원인을 찾았습니다!

    하지만 오답인 case 를 찾아야 하는데 못찾고 있습니다..
    (제가 만든 TC 들은 모두 정답 나오고 있습니다...)

    코딩 경험이 많이 부족하여 이런경우 어떻게 해야할지를 모르겠습니다.

    이럴때, 어떤식으로 접근을 해야 할지요?


    [시간초과 해결]

    안녕하세요.

    저는 초보는 아니지만, 실력이 많이 부족한 프로그래머입니다.

    알고스팟을 알게 되었고, 어렵지만 열심히 하다보면 내공이 쌓일것 같아 열심히 문제를 풀고 있는 중입니다.
    그런데 FIRE 문제에서 막혔네요...

    시간 초과가 될만한 사유가 있는지, 고수님들의 조언 부탁드립니다.

    감사합니다.

    FIRE(봉화대 설치)

    #include <stdio.h>
    #define MAX 100000 + 2
    
    int TC;
    int N;
    int P;
    int ARR[MAX+MAX];
    unsigned long long sum;
    int from1, to1;
    int from2, to2;
    int start, end;
    int min, minindex;
    
    int main(void)
    {
       scanf("%d",&TC);
    
        for(int i=0;i<TC;i++)
        {
            scanf("%d %d", &N, &P);
    
            for(int j1=0;j1<N;j1++)
            {
                scanf("%d", &ARR[j1+1]);
            }
    
            // 예외1 : P=1 인 경우
            if(P==1) {
                for(int j2=1;j2<N+1;j2++)
                    sum = sum + ARR[j2];
    
                printf("%llu\n",sum);
                sum=0;
    
                min = 0;
                minindex = 0;
                for(int j3=0;j3<N;j3++)
                    ARR[j3+1]=0;
                continue;
            }
            // 예외2 : N <= P 인 경우 가장 작은 곳 1개가 답
            if(N<=P) {
                sum = MAX;
                for(int j4=1;j4<N+1;j4++)
                {
                    if(sum>ARR[j4]) sum = ARR[j4];
                }
                printf("%llu\n",sum);
                sum=0;
    
                min = 0;
                minindex = 0;
                for(int j5=0;j5<N;j5++)
                    ARR[j5+1]=0;
                continue;
            }
    
            // 처음부터 시작하여 P개씩 묶고, 마지막 부터 시작하여 P개씩 묶는다.
            // 겹치는 부분중에서 최소 값을 찾되 동일한 값이면 나중것을 선택한다.
            // 이렇게 선택된 것을 모두 더하면 답이 된다.
            for(;minindex<N+1;)
            {
                from1 = minindex + 1;
                to1 = from1+P-1;
                from2 = minindex + (N-minindex)%P + 1;
                to2 = from2+P-1;
    
                min = MAX;
                start = from2;
                end = to1;
    
                for(int k=start;k<=end;k++)
                {
                    if(ARR[k]<=min)
                    {
                        minindex = k;
                        min = ARR[k];
                    }
                }
    
                // 검토, 겹치는 값보다 이전의 값이 작은 경우도 있으므로 그것을 체크한다.
                for(int l=minindex-1;l>=from1;l--)
                {
                    if(l+P+1>N+1) break;
                    for(int m=1;m<=P;m++)
                    {
                        if(l+m < minindex) break;
                        if(ARR[l]+ARR[l+m] <= min)
                        {
                            minindex = l;
                            min = ARR[l];
                        }
                    }
                }
    
                //printf("%d ",ARR[minindex]);
                sum = sum + min;
    
            }
    
            printf("%llu\n",sum);
            sum=0;
    
            min = 0;
            minindex = 0;
            for(int j6=0;j6<N;j6++)
                ARR[j6+1]=0;
        }
    
        return 0;
    }
    

    10년 전
7개의 댓글이 있습니다.
  • kwangswei
    kwangswei

    기본적으로 소스코드는 보기 좋게 태그 써서 넣어주시고 문제도 링크 부탁 드립니다. 글 쓰실 때 밑에 도움말이 있습니다.


    10년 전 link
  • JongMan
    JongMan

    N=10만, P=N-1이라고 생각해보세요. 시간 안에 돌아갈까요?
    랜덤 데이터를 한번 생성해서 넣어보셔도 좋습니다. :-)


    10년 전 link
  • gloryof11
    gloryof11

    JongMan 님 감사합니다!
    하지만, 이번에는 오답이 나오는데, 해당 TC 를 못찾아서 디버깅을 못하고 있습니다;; 혹시 이런경우 어떤식으로 문제 해결을 해야 할까요?
    (다양한 TC 를 생성해야 하는데, 이게 어려운것 같습니다;;)


    10년 전 link
  • kcm1700
    kcm1700

    저의 경우에는 오답이 되는 케이스를 찾기보다는 방법의 정당성을 증명하는데 시간을 먼저 보냅니다. (보통은 코드를 짜기 전에) 직관적으로 그럴 것 같다는 것 말고 사용한 알고리즘이 항상 정확한 답을 낸다는 것을 증명하는 것을 시도해보세요.

    증명을 시도하는 것만으로도 반례를 얻어낼 수 있는 경우가 많습니다.

    반례는 아래에 적어둘게요. 정 모르겠으면 열어보세요. 반례를 찾을 때마다 찾은 반례의 종류가 작동하도록 조금씩 보완해나가는 방식은 추천하지 않습니다.

    10 6
    1 2 3 4 101 100 7 8 9 10


    10년 전 link
  • gloryof11
    gloryof11

    kcm1700 님의 조언을 바탕으로 현재 알고리즘은 문제를 해결 할 수 없다는 결론을 내렸습니다. 감사합니다!


    10년 전 link
  • gloryof11
    gloryof11

    기적적으로 문제를 해결하였습니다! kcm1700 님 조언에 다시한번 감사를 드립니다!


    10년 전 link
  • kcm1700
    kcm1700

    와, 축하합니다, 힌트도 없이 결국 해결하셨군요!


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