본문 바로가기

problem solving

9446번: 텀 프로젝트

보기보다 까다로운 문제다. (너무 지저분해서 내 코드를 완벽히 설명하기가 힘들 거 같다...)

처음에는 쌍을 찾기위해서 check 배열을 선언해서 각 testCase마다 초기화했었다.

하지만 시간이 한참 초과되는 걸 보고 check 배열을 초기화하는 대신 각 testCase마다 특정 수를 이용해서

하나의 check 배열을 재활용할 수 있도록 했다.

DFS 함수에서 정답을 찾으면 skip 배열에 해당 testCase에 해당하는 특정 수를 부여해주고

이후 탐색한 순서 역순으로 되돌아가면서

해당하는 수의 skip 배열에 testCase에 해당하는 특정 수를 부여하고 sum을 +1 한다.

DFS함수가 종료되면 쌍을 갖춘 학생들의 합인 sum과 총 학생 수인 len의 차이를 출력한다.

 

#include <iostream>
#include <cstring>
 
int check[100001= { 0 };
int skip[100001= { 0 };
int map[100001= { 0 };
int sum = 0;
 
void DFS(int stu[], int start, int cur, int seq) {
    check[cur] = seq;
 
    if(start == cur && skip[cur] != seq) {
        skip[cur] = seq;
        sum++;
        return;
    }
    if(stu[cur] == cur || check[stu[cur]] == seq || skip[stu[cur]] == seq) {
        check[stu[cur]] = 0;
        return;
    }
 
    DFS(stu, start, stu[cur], seq);
    if(skip[stu[cur]] == seq && sum > 0) {
        skip[cur] = seq;
        sum++;
    }
    else {
        check[stu[cur]] = 0;
    }
}
 
int main(void) {
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(NULL);
 
    memset(check, 0sizeof(check));
    memset(skip, 0sizeof(skip));
    memset(map, 0sizeof(map));
 
    int testCase;
    std::cin >> testCase;
 
    int len, seq = 0;
    for(int i = 0; i < testCase; i++) {
        std::cin >> len;
        sum = 0;
       seq = testCase + 1;
        for(int i = 1; i <= len; i++) {
            std::cin >> map[i];
        }
 
        for(int idx = 1; idx <= len; idx++) {
            if(skip[idx] == seq) continue;
            DFS(map, idx, map[idx], seq);
        }
        std::cout << len - sum << "\n";
    }
 
    return 0;
}
cs

'problem solving' 카테고리의 다른 글

10610번: 30  (0) 2020.03.04
9613번: GCD 합  (0) 2020.03.04
9019번: DSLR  (0) 2020.03.03
7576번: 토마토  (0) 2020.03.03
6588번: 골드바흐의 추측  (0) 2020.03.03