그래프 탐색 - 2668번: 숫자고르기

jisu_log·2025년 5월 31일

알고리즘 문제풀이

목록 보기
35/105

1) 아래 숫자들의 set으로부터 가능한 모든 부분집합을 생성하여 해당 집합의 아래 숫자 리스트를 구해서 정렬 후 비교 시
조합 + 정렬 + 비교를 반복하므로 최악의 시간복잡도는 O(2^n * nlogn) 이상이므로 시간초과 발생함
2) 문제 구조가 그래프의 연결 구조(숫자=노드, num_list=간선)임!
즉 방향 그래프에서 각 노드마다 하나의 방향만 있으므로 전체가 여러 개의 사이클로 나뉨
-> 어떤 숫자들을 골라서 정렬했을 때, 그 숫자들이 가리키는 값들도 정렬했을 때 똑같아야 하는 조건은 사이클을 이루는 숫자만 성립함!

'''
# 시간 초과
n = int(input())
num_list = []

for _ in range(n):
    line = int(input())
    num_list.append(line)


def get_combinations(arr, r):
    result = []

    def dfs(start, path):
        if len(path) == r:
            result.append(path[:])
            return
        for i in range(start, len(arr)):
            dfs(i + 1, path + [arr[i]])
    
    dfs(0, [])
    return result


def get_max(num_list, num_set_list, n):
    is_done = False

    for i in range(0, len(num_set_list)):
        res = get_combinations(num_set_list, len(num_set_list) - i)

        #print(res)
        for combi in res:
            under_nums = []
            for idx in combi:
                under_nums.append(num_list[idx - 1]) # 인덱스 0부터 시작하도록 -1 해줘야 함
            under_nums.sort() # 오름차순 정렬

            # 위 숫자 조합과 아래 숫자 조합이 일치한다면 출력 후 종료
            if combi == under_nums:
                print(len(combi))
                for num in combi:
                    print(num)
                is_done = True
                break
        if is_done:
            break
    return



num_set = set(num_list)
num_set_list = list(num_set)

get_max(num_list, num_set_list, n)


'''


# ----

n = int(input())
num_list = [int(input()) for _ in range(n)]

result = []

for i in range(n):

    visited = [False] * n
    idx = i

    while not visited[idx]: # 아직 방문하지 않은 곳이라면
        visited[idx] = True
        idx = num_list[idx] - 1 # 0부터 시작하도록 함

    # 자기자신으로 돌아왔다면 정답에 추가
    if i == idx:
        result.append(idx + 1) # 추가할 땐 1부터 시작하게 함

    
# 오름차순 정렬
result.sort()

# 정답 출력
print(len(result))
for num in result:
    print(num)

0개의 댓글