본문 바로가기
Python3/백준 알고리즘

2022.02.28 [백준] (python 파이썬) 암호 만들기

by ian's coding 2022. 2. 28.
728x90
반응형

 

https://www.acmicpc.net/problem/1759

 

1759번: 암호 만들기

첫째 줄에 두 정수 L, C가 주어진다. (3 ≤ L ≤ C ≤ 15) 다음 줄에는 C개의 문자들이 공백으로 구분되어 주어진다. 주어지는 문자들은 알파벳 소문자이며, 중복되는 것은 없다.

www.acmicpc.net


풀이

우선 조건을 생각해보자.

  • 암호에서 모음이 최소 1개이상, 자음이 2개이상 있어야한다.
  • 암호는 알파벳의 증가순으로 배열된다.

위의 두 조건을 보면 우선 입력받은 알파벳을 오름차순으로 정렬해야 한다.

그래서 입력받은 alpha배열을 정렬하고 모음 정렬을 만들어준다.

이후, combinations함수를 이용해 alpha배열에서 L개를 뽑아준다. 이 때, 순서는 고려하지 않으므로 뽑히는 모든 배열은 알파벳이 오름차순으로 정렬한다.

cnt을 만들어 만들어진 배열에서 모음의 갯수를 카운트할 것이다.

만들어진 배열을 for문을 돌려 모음의 개수를 카운트해준다.

문제의 조건에서 모음이 1개이상, 자음이 2개이상 암호에 들어있어야한다.

이것을 생각해보면 모음이 0보다 많고 L-2보다 작거나 같으면 모음도 최소1개 이상 들어있고, 자음도 2개이상 들어있게 된다. 그래서 위의 조건을 만족하는 배열을 출력해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from itertools import *
 
L,C=map(int,input().split())
alpha=list(input().split())
alpha.sort()
m=['a','e','i','o','u']
for comb in combinations(alpha,L):
    cnt=0
    for i in comb:
        if i in m:
            cnt+=1
    if cnt>0 and cnt<=(L-2):
        print(''.join(i for i in comb))
 
cs

 

아래의 코드는 백트래킹(DFS)를 이용하여 코드를 작성했다.

위 코드와 같이 알파벳을 입력받은 다음 오름차순 정렬 후, password함수를 실행시켰다. 파라미터는 문자열의 길이인 depth, 비밀번호가 오름차순으로 되야하기 때문에 for문의 시작점을 정해줄 start, 비밀번호를 저장할 string 총 3가지이다.

함수안의 코드를 보면, 무선 정지조건으로 string의 길이가 L과 같으면 해당 문자열안에 모음이 몇개가 들어있는지 확인한다. 그리고 모음의 개수가 0보다 크고 L-1보다 작으면 해당 문자열을 출력한다. 여기서 범위가 L-1보다 작은 조건을 준 이유는 자음이 최소 2개이상 들어가야 하기 때문에 자음의 개수를 모음의 개수에서 구했다. 

그리고 문자열을 채우기 위한 for문을 start에서 C까지의 범위로 돌려 문자열을 채웠다.

여기서 string.pop()을 꼭해주어야 한다. 이유는 다음의 경우를 확인하기 위해서이다. 만약 이것을 해주지않으면 문자열은 이전의 값을 지우지않고 추가만 될것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
L,C=map(int, input().split())
alpha=list(input().split())
alpha.sort()
vowels=['a','e','i','o','u']
 
def password(depth, start, string):
    if len(string)==L:
        cnt=0
        for vowel in vowels:
            if vowel in string:
                cnt+=1
        if 0<cnt<L-1:
            print(''.join(string))
            return
 
    for i in range(start,C):
        string.append(alpha[i])
        password(depth+1,i+1,string)
        string.pop()
 
password(0,0,[])
cs

 

 

 

728x90
반응형

댓글