2668번: 숫자고르기
세로 두 줄, 가로로 N개의 칸으로 이루어진 표가 있다. 첫째 줄의 각 칸에는 정수 1, 2, …, N이 차례대로 들어 있고 둘째 줄의 각 칸에는 1이상 N이하인 정수가 들어 있다. 첫째 줄에서 숫자를 적절
www.acmicpc.net
문제
세로 두 줄, 가로로 N개의 칸으로 이루어진 표가 있다. 첫째 줄의 각 칸에는 정수 1, 2, …, N이 차례대로 들어 있고 둘째 줄의 각 칸에는 1이상 N이하인 정수가 들어 있다. 첫째 줄에서 숫자를 적절히 뽑으면, 그 뽑힌 정수들이 이루는 집합과, 뽑힌 정수들의 바로 밑의 둘째 줄에 들어있는 정수들이 이루는 집합이 일치한다. 이러한 조건을 만족시키도록 정수들을 뽑되, 최대로 많이 뽑는 방법을 찾는 프로그램을 작성하시오. 예를 들어, N=7인 경우 아래와 같이 표가 주어졌다고 하자.
이 경우에는 첫째 줄에서 1, 3, 5를 뽑는 것이 답이다. 첫째 줄의 1, 3, 5밑에는 각각 3, 1, 5가 있으며 두 집합은 일치한다. 이때 집합의 크기는 3이다. 만약 첫째 줄에서 1과 3을 뽑으면, 이들 바로 밑에는 정수 3과 1이 있으므로 두 집합이 일치한다. 그러나, 이 경우에 뽑힌 정수의 개수는 최대가 아니므로 답이 될 수 없다.
입력
첫째 줄에는 N(1≤N≤100)을 나타내는 정수 하나가 주어진다. 그 다음 줄부터는 표의 둘째 줄에 들어가는 정수들이 순서대로 한 줄에 하나씩 입력된다.
출력
첫째 줄에 뽑힌 정수들의 개수를 출력하고, 그 다음 줄부터는 뽑힌 정수들을 작은 수부터 큰 수의 순서로 한 줄에 하나씩 출력한다.
코드
시간 초과 코드
n = int(input())
arr = [0]
for _ in range(n):
arr.append(int(input()))
ans = []
def dfs(idx, first, second):
global ans
if idx == n+1:
return
first.add(idx)
second.add(arr[idx])
if len(ans) < len(first) and first == second:
ans = list(first)
dfs(idx+1, first, second)
first.discard(idx)
second.discard(arr[idx])
dfs(idx+1, first, second)
dfs(1, set(), set())
print(len(ans))
print(*sorted(ans), sep='\n')
이렇게 하면 이진트리 모양으로 최대 깊이 100까지 가서 시간 초과가 발생하는거 같다.
그래서 구글링을 해보니 사이클이 발생하는지 체크해서 풀면 되는거였다. 이게 무슨 말이냐면 문제의 예제에서 두번째 줄을 출발 노드, 첫번째 줄을 도착 노드로 생각하여 그래프를 그려보면 다음과 같다.
첫째줄에서 뽑은 정수들의 집합과 그 정수들 바로 아래 둘째 줄의 정수들의 집합이 일치할 때는 사이클을 이루는 것을 볼 수 있다. 따라서 인접 리스트를 만들어서 탐색하며 사이클을 이루는 경우들을 찾으면 된다.
n = int(input())
arr = [[] for _ in range(n+1)]
for i in range(1, n+1):
arr[int(input())].append(i)
ans = []
def dfs(node, visited):
visited.add(node)
checked[node] = True
for nx in arr[node]:
if nx not in visited:
dfs(nx, set(visited))
else: # 사이클 발생
ans.extend(list(visited))
return
checked = [False] * (n+1)
for i in range(1, n+1):
if not checked[i]:
dfs(i, set())
print(len(ans))
print(*sorted(ans), sep='\n')
'문제풀이 > DFS_BFS' 카테고리의 다른 글
[Python/파이썬] 백준 1600번 말이 되고픈 원숭이 (0) | 2023.06.19 |
---|---|
[Python/파이썬] 백준 13023번 ABCDE (0) | 2023.04.25 |
[Python/파이썬] 백준 17836번 공주님을 구해라! (0) | 2023.04.24 |
[Python/파이썬] 백준 16234번 인구 이동 (0) | 2023.03.02 |
[Python/파이썬] 백준 14620번 꽃길 (0) | 2023.03.01 |