728x90
반응형
문제 링크
https://www.acmicpc.net/problem/1017
정답 코드는 아래와 같습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
import sys
import collections
import math
VMAX = 52
SOURCE = 50
SINK = 51
NN = 2000
primes = [True] * (NN)
primes[1] = False
for i in range(2, NN):
if primes[i]:
for j in range(i*2, NN, i):
primes[j] = False
def isPrime(val):
return primes[val]
def bfs(flow, capacity, source, sink):
parent = [-1] * VMAX
q = collections.deque([source])
parent[source] = source
while len(q) != 0:
item = q.popleft()
for i in range(VMAX):
if parent[i] == -1 and capacity[item][i] - flow[item][i]:
q.append(i)
parent[i] = item
return parent
def maxFlow(capacity, source, sink, flow):
rst = 0
while True:
parent = bfs(flow, capacity, source, sink)
if parent[sink] == -1:
return rst
#minimum
node = sink
m = math.inf
while node != source:
m = min(m, capacity[parent[node]][node] - flow[parent[node]][node])
node = parent[node]
#add
rst += m
node = sink
while node != source:
flow[parent[node]][node] += m
flow[node][parent[node]] -= m
node = parent[node]
def solve():
n = int(sys.stdin.readline().rstrip())
arr = list(map(int, sys.stdin.readline().rstrip().split()))
even = []
odd = []
for i in range(n):
if arr[i] % 2 == 0:
even.append(i)
else:
odd.append(i)
# build graph
graph = [[0] * VMAX for _ in range(VMAX)]
for i in even:
graph[SOURCE][i] = 1
for i in odd:
graph[i][SINK] = 1
for i in even:
for j in odd:
if isPrime(arr[i] + arr[j]):
graph[i][j] = 1
rst = []
while True:
flow = [[0] * VMAX for _ in range(VMAX)]
val = maxFlow(graph, SOURCE, SINK, flow)
if val == n // 2:
if arr[0] % 2 == 0: # even
for i in odd:
if flow[0][i] == 1:
rst.append(arr[i])
graph[0][i] = 0
else:
for i in even:
if flow[i][0] == 1:
rst.append(arr[i])
graph[i][0] = 0
else:
break
if len(rst) == 0:
print(-1)
else:
rst.sort()
for item in rst:
print(item, end = ' ')
print("")
solve()
|
cs |
728x90
숨은 조건을 찾는 것이 이 문제를 푸는데 상당히 중요하게 작용합니다.
숨은 조건이란, 중복하지 않는 자연수의 합으로 만들 수 있는 소수는 홀수밖에 없으며,
두 수를 더해서 홀수가 되기 위해서는 반드시 하나는 짝수이고, 다른 하나는 홀수여야 한다는 것입니다.
이것을 알아내기만 한다면, 소수 구하기와 이분매칭을 공부하신 분이라면 어렵지 않게 풀 수 있는 문제입니다.
소수 구하기: https://roamingman.tistory.com/70
이분 매칭: https://roamingman.tistory.com/19
다만, 과연 실전에서 이런 숨은 조건을 잘 찾아낼 수 있을지는 생각해 봐야할 문제입니다.
다른 문제 풀이를 하면서, 풀이가 떠오르지 않을 때 어떻게 해야 좋을지에 대해서 제가 써 놓은 글이 있습니다.
학습하시는데 참고가 되길 바랍니다.
https://roamingman.tistory.com/46
풀이는 아래 영상을 참고 바랍니다.
https://www.youtube.com/watch?v=sAzFsEoLPko
저작권 라이선스: CC BY (출처만 표시하면 자유롭게 이용 가능)
728x90
반응형
'백준(BOJ) 문제 풀이' 카테고리의 다른 글
백준 11651번 문제(좌표 정렬하기 2) 파이썬(Python) 풀이 [로밍맨] (3) | 2022.05.09 |
---|---|
백준 11650번 문제(좌표 정렬하기) 파이썬(Python) 풀이 [로밍맨] (0) | 2022.05.03 |
백준 1924번 문제(2007년) 파이썬(Python) 풀이 [로밍맨] (3) | 2022.03.15 |
백준 1929번 문제(소수 구하기) 파이썬(Python) 풀이 [로밍맨] (0) | 2022.03.02 |
백준 1654번 문제(랜선 자르기) 파이썬(Python) 풀이 [로밍맨] (0) | 2022.02.15 |