import sys
input = sys.stdin.readline
def permutation(ind,C,string_list,particle_order):
global result
if ind == C:
if len(string_list)>0:
result.add(''.join(string_list))
else:
result.add('EMPTY')
return
else:
for i in range(1,N+1):
command_order = particle_order[i]
if command_order >= len(order_list[i]):
continue
else:
if not visited[i][command_order]:
order_num = order_list[i][command_order]
new_stringlist = string_list[:]
check_error = False
for order in card_command[order_num]:
if order[0] == 'ADD':
new_stringlist.append(order[1])
else:
remove_index = int(order[1])
if len(new_stringlist) > remove_index:
new_stringlist.pop(remove_index)
else:
check_error = True
break
if check_error:
result.add('ERROR')
continue
else:
visited[i][command_order] = True
particle_order[i] += 1
permutation(ind+1,C,new_stringlist,particle_order)
visited[i][command_order] = False
particle_order[i] -= 1
N,C = map(int,input().split())
order_list = [[] for _ in range(N+1)]
for ind in range(1,N+1):
input_list = list(map(int,input().split()))
order_list[ind] = input_list[1:]
card_command = [[] for _ in range(C+1)]
for ind in range(1,C+1):
commands = list(input().rstrip().split(','))
temp = []
for command in commands:
new_command = list(command.split(' '))
temp.append(new_command)
card_command[ind] = temp
result = set()
visited = [[False for _ in range(len(order_list[ind]))] for ind in range(N+1)]
particle_order = [0 for _ in range(N+1)]
permutation(0,C,[],particle_order)
result = list(result)
result.sort()
for i in range(len(result)):
sys.stdout.write(result[i]+'\n')
이 문제는 구현을 하면 되는 문제였다. 여기서 주의해야할 점은, 사람1이 소지한 순서대로 카드를 낸다는것이다.
그러므로 먼저 사람1~ 사람N 까지의 순열을 구하는데 느낌은
사람이 가지고 있는 카드의 수만큼 중복되게 수를 구해주고 순열을 구해주는 느낌으로 풀면된다.
만약 사람1이 카드를 4장 사람2가 카드를 2장 사람3가 카드를 3장 가지고 있다고 하면
[1,1,1,1,2,2,3,3,3] 이런식으로 리스트를 만들어놓고 순열을 구해도 된다.
나 같은 경우엔 각 사용자별로 card_command에 각 명령어를 파싱해서 저장을 시켜주었다.
그리고 particle_order를 이용해서, 각 사용자가 몇번재 카드를 썼는지 확인을했다.
그 뒤에는 재귀를 이용해서 백트래킹을 해주었다.
particle_order의 숫자가 사람1의 전체 명령어 수와 같게 되면, 선택을 못하게 if문으로 판별을 해주었다.
prarticle_order가 각 사람의 명령어 수보다 적다면, 인제 이 명령어가 가능한지 판단을 한다.
명령을 수행하다가 error가 발생시, result에 add를 추가해주고, 다음번으로 넘어가준다.
그리고 명령을 정확하게 수행하면, visited[사람의 인덱스][그 사람의 몇번째 카드]에 방문을 표시를 해준다.
그리고 particle_order의 값을 1 늘려주고, 재귀를 해준다.
이렇게 재귀를 하면서 전체 카드수를 다 쓰면, 모든 명령을 잘 수행한것이 된다. 그러면 그때의 결과를 result에 추가하는데,
아무것도 안남아있으면 EMPTY를 추가해주면 된다.
그리고 재귀를 하다가 복귀하게 되었을때에는 visited를 초기화해주고, particle_order도 1을 빼주면 된다.
이 문제는 백트래킹을 어떻게, 그리고 순열을 어떻게 응용해서 하는지에 대한 문제였다.
그래서 긴 문제 지문에 비해 많이 어려운 편은 아니였다.
'알고리즘 > 백준' 카테고리의 다른 글
[BOJ/백준] 21778 가희와 프로세스 2 (0) | 2021.06.05 |
---|---|
[BOJ/백준] 21777 리버스 가희와 프로세스 (0) | 2021.06.05 |
[BOJ/백준] 21775 가희와 자원 놀이 (0) | 2021.06.02 |
[BOJ/백준] 21774 가희와 로그 파일 (0) | 2021.06.01 |
[BOJ/백준] 21773 가희와 프로세스 1 (0) | 2021.05.27 |