Home 백준 1091번 카드 섞기
Post
Cancel

백준 1091번 카드 섞기

정보

문제 바로가기 [클릭]

난이도: Gold5

관련 개념: #구현 #시뮬레이션


조건

시간 제한메모리 제한
2초128 MB

문제

지민이는 카지노의 딜러이고, 지금 3명의 플레이어(0, 1, 2)가 있다. 이 게임은 N개의 카드를 이용한다. (0 ~ N-1번)

일단 지민이는 카드를 몇 번 섞은 다음에, 그것을 플레이어들에게 나누어 준다. 0번째 위치에 있던 카드가 플레이어 0에게 가고, 1번째 위치에 있던 카드는 플레이어 1에게 가고, 2번째 위치에 있던 카드는 플레이어 2에게 가고, 3번째 위치에 있던 카드는 플레이어 0에게 가고, 이런식으로 카드를 나누어 준다. 하지만, 지민이는 약간 사기를 치려고 한다.

지민이는 처음에 카드를 섞기 전에 카드의 순서를 알고 있고, 이 정보를 이용해 각 카드가 특정한 플레이어에게 보내지게 할 것이다.

카드를 한 번 섞을 때는 주어진 방법을 이용해서만 섞을 수 있고, 이 방법은 길이가 N인 수열 S로 주어진다. 카드를 한 번 섞고 나면 i번째 위치에 있던 카드는 S[i]번째 위치로 이동하게 된다.

각 카드가 어떤 플레이어에게 가야 하는지에 대한 정보는 길이가 N인 수열 P로 주어진다. 맨 처음 i번째 위치에 있던 카드를 최종적으로 플레이어 P[i] 에게 보내야한다.

지민이가 목적을 달성하기 위해 필요한 카드 섞는 횟수의 최솟값을 구하는 프로그램을 작성하시오.


입력

첫째 줄에 N이 주어진다. N은 3보다 크거나 같고, 48보다 작거나 같은 3의 배수이다.

둘째 줄에 길이가 N인 수열 P가 주어진다. 수열 P에 있는 수는 0, 1, 2 중 하나이다.

셋째 줄에 길이가 N인 수열 S가 주어진다. 수열 S에 있는 수는 모두 N-1보다 작거나 같은 자연수 또는 0이고 중복되지 않는다.


출력

첫째 줄에 몇 번 섞어야 하는지 출력한다. 만약, 섞어도 섞어도 카드를 해당하는 플레이어에게 줄 수 없다면, -1을 출력한다.


예제 입출력 1

입력

1
2
3
3
2 0 1
1 2 0

출력

1
2

예제 입출력 2

입력

1
2
3
6
0 1 2 0 1 2
1 4 0 3 2 5

출력

1
0

예제 입출력 3

입력

1
2
3
3
1 0 2
0 2 1

출력

1
-1

예제 입출력 4

입력

1
2
3
12
1 1 2 0 2 0 1 0 2 2 1 0
5 0 9 7 1 8 3 10 4 11 6 2

출력

1
59

코드(파이썬)

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
def back_track(ch):
    v[ch] = 1
    
    if len(stack) == l:
        if sum([v[ch] for ch in mo]) > 0 and sum([v[ch] for ch in za]) > 1:
            print("".join([chr(ch+ord('a')) for ch in stack]))
    else:
        for n_ch in alpha[index[ch]+1:]:
            stack.append(n_ch)
            back_track(n_ch)
            stack.pop()
            
    v[ch] = 0

l, c = map(int, input().split())
alpha = sorted([ord(ch)-ord('a') for ch in input().split()])

mo_all = [ord('a')-ord('a'), ord('e')-ord('a'), ord('i')-ord('a'), ord('o')-ord('a'), ord('u')-ord('a')]
za_all = [i for i in range(26) if i not in mo_all]
mo = set(alpha).difference(za_all)
za = set(alpha).difference(mo)

v = [0 if i in alpha else 1 for i in range(26)]
index = [alpha.index(i) if i in alpha else 0 for i in range(26)]
stack = []

for ch in alpha:
    stack.append(ch)
    back_track(ch)
    stack.pop()


특이사항

  • 내 코드(48,248KB, 1000ms)에 비해 우수한 코드(바로가기, 30,840KB, 512ms)와 비교
    • 1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      
      from sys import stdin
      
      n = int(input())
      p = list(map(int, input().split()))
      s = list(map(int, stdin.readline().split()))
      
      answer = [i%3 for i in range(n)]
      temp = p
      
      def shuffle(list, shup):
          arr = [0]*n
          for i in range(n):
              arr[shup[i]] = list[i]
          return arr
      
      cnt = 0
      while p != answer:
          p = shuffle(p, s)
          cnt += 1
          if p == temp:
              print(-1)
              exit()
      
      print(cnt)
      
    • 저장방식
      • 기존: 문자형
      • 개선: 정수형
    • 중복 확인
      • 기존: v 세트
      • 개선: 문자열을 섞다보면 결국 처음 문자열로 돌아가므로 해당 문자열만 확인

참고문헌

-

This post is licensed under CC BY 4.0 by the author.

백준 1759번 암호 만들기

백준 1620번 나는야 포켓몬 마스터 이다솜

Comments powered by Disqus.