Allergy 문제 시간초과가 왜 나는지 모르겠네요 ㅜㅠ

  • Jinsanger
    Jinsanger

    Allergy 문제를 풀고 있는 초보 개발자입니다 ㅠ
    단순 탐색문제라고 하길래 쉬워보여서(?) 도전했는데 고생하고 있네요 ㅜㅜ
    일단 제가 사용한 방법은 포인터를 이용한 방법입니다.
    구조체를 만들어 놓고 구조체를 통해서 음식이 친구들의 식성에 부합하는지 여부를 카운팅하는 방식으로, 즉, 음식 노드들을 순회하면서 음식이 가리키는 친구들의 식성(favor 배열)을 ++ 하는 방식으로 구현했습니다.
    그리고 dishes 배열을 통해서 중복 탐색을 막는 식으로 구현했습니다.

    나름 식성이 부족한 친구들을 위주로 탐색하게 하는 등의 가지치기 작업을 수행하는데 시간 초과가 뜨네요 ㅜ

    혹시 기법이 잘못됬는지 피드백좀 부탁드립니다.

    #include <stdio.h>
    #include <string.h>
    
    typedef struct plates{
        int friend_num;
        int* friends[50];
    }plates;
    
    static int N=0;
    static int M=0;
    static char names[50][11] = {0, };
    static int favor[50] = {0, };
    static plates Foods[50] = {0, };
    static int dishes[50] = {0, };
    
    int Allergy(int count, int bound){
        int solution = 987654321;
        int result = count;
        int i=0, j=0;
        int ret=0;
    
        int flag = 0;
        while(flag<N && favor[flag] != 0)   flag++;
        if(flag == N)
            return result;
    
        for(i=bound; i<M; i++){
            if(dishes[i] == 0){
                int flag = 0;
                while(flag<Foods[i].friend_num && (*(Foods[i].friends[flag])) > 0) flag++;
                if(flag == Foods[i].friend_num)
                    continue;
                dishes[i] = 1;
                for(j=0; j<Foods[i].friend_num; j++)
                    (*(Foods[i].friends[j]))++;
    
                ret = Allergy(result+1, i);
                if(ret < solution)
                    solution = ret;
    
                for(j=0; j<Foods[i].friend_num; j++)
                    (*(Foods[i].friends[j]))--;
                dishes[i] = 0;
            }
        }
        return solution;
    }
    
    int main(void){
        int T=0;
        int i=0, j=0, k=0;
        scanf("%d", &T);
        while(T-->0){
            int sol = 0;
            int man_idx = 0;
            scanf("%d %d", &N, &M);
            for(i=0; i<N; i++)
                scanf("%s", names[i]);
            for(i=0; i<M; i++){
                scanf("%d", &Foods[i].friend_num);
                man_idx = 0;
                for(j=0; j<Foods[i].friend_num; j++){
                    char tempName[11] = {0, };
                    scanf("%s", tempName);
                    for(k=0; k<N; k++){
                        if(strcmp(names[k], tempName) == 0){
                            Foods[i].friends[j] = &favor[k];
                            break;
                        }
                    }
                }
            }
            sol = Allergy(0, 0);
            printf("%d\n", sol);
        }
        return 0;
    }
    

    10년 전
2개의 댓글이 있습니다.
  • Kureyo
    Kureyo

    오류가 있어서 TLE를 받는것보다는 그냥 단순히 느려서 그런거같습니다;

    항상 count는 증가하기 때문에 '현재까지 알려진 글로벌한 best solution'값 이상에 count가 도달하면 가지칠수 있습니다. 한 번 도전해보세요 :)


    10년 전 link
  • Jinsanger
    Jinsanger

    스포일러를 봤습니다. 하하 ;;;
    말씀해주신데로 가지치니까 정말 마법처럼 되네요. ㅎㅎ 감사합니다
    많이 배우겠습니다 ㅋㅋ


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