-
Notifications
You must be signed in to change notification settings - Fork 2
20-hyeokbini #72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
20-hyeokbini #72
Conversation
|
예전에 고생했던 기억이 나는 문제네요. 실력이 부족할 때 왜 못풀었냐 생각해보면 문제들을 복잡하게 생각하려 했던 경향이 있어서 그랬던 것 같습니다. 대부분은 완전탐색으로 풀리는 경우도 많은 것 같아요. 수고하셨습니다! 모음사전``cpp #include<bits/stdc++.h> using namespace std; } int solution(string word) { } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
으아 20주차 PR은 제가 제일 먼저 올리려고 벼르고 있었는데 선수 뺏겼네요 하하...
사용할 글자는 A, E, I, O, U 총 5개이고, 길이는 1~5이므로
어떤 자리 i(0부터)의 글자를 하나 올리면, 그 뒤에 올 수 있는 모든 조합 수만큼 “통째로 건너뛴다”고 볼 수 있어요.
이 '건너뛰는 묶음 크기'를 저는 자리별 가중치로 뒀습니다.
자리 i에서 뒤에 붙을 수 있는 길이는 0..(4-i)이고, 각 길이마다 경우의 수는 5^k개이므로

수치로는 W = [781, 156, 31, 6, 1]로 뒀습니다.
예를 들면, "AAAAE"라 가정했을 때
0번 자리 A: 0*781 + 1 = 1
1번 자리 A: 0*156 + 1 = 1 → 누적 2
2번 자리 A: 0*31 + 1 = 1 → 누적 3
3번 자리 A: 0*6 + 1 = 1 → 누적 4
4번 자리 E: 1*1 + 1 = 2 → 누적 6
이렇게 나옵니다.
#include <string>
#include <vector>
using namespace std;
int solution(string word) {
int weight[5] = {781, 156, 31, 6, 1};
auto val = [](char c) {
if (c == 'A') {
return 0;
} else if (c == 'E') {
return 1;
} else if (c == 'I') {
return 2;
} else if (c == 'O') {
return 3;
} else {
return 4;
}
};
int answer = 0;
for (int i = 0; i < (int)word.size(); i++) {
answer += val(word[i]) * weight[i] + 1;
}
return answer;
}문제 푸시느라 고생 많으셨어요! 방학 끝나기 전에 함 봅시다잉
그립습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
itertools.product 사용 풀이
저는 문제를 보고 AEIOU 중 길이가 1~5인 중복순열의 개수를 생각해보고 그 값은
중복순열을 만들어주는 itertools 모듈의 product 함수를 사용해서 길이가 1부터 5인 문자열을 lst에 담고 이를 정렬한 후, 찾는 word의 인덱스를 반환하도록 했습니다.
from itertools import product
def solution(word):
lst = []
for length in range(1, 6):
for p in product("AEIOU", repeat=length):
lst.append(''.join(p))
lst.sort()
return lst.index(word) + 1product 함수에 대해 간단히 설명하자면, 하나 이상의 iterable(리스트, 튜플, 문자열 등)을 인자로 받아서, 각 iterable에서 가능한 모든 조합의 데카르트 곱을 생성하는 함수입니다.
itertools.product(*iterables, repeat=1)사용 예시는 다음과 같습니다.
print(list(product([1, 2], ['A', 'B'])))
# [(1, 'A'), (1, 'B'), (2, 'A'), (2, 'B')]
print(list(product([1, 2], repeat=2)))
# [(1, 1), (1, 2), (2, 1), (2, 2)]위 문제처럼 AEIOU 문자열 중에서 중복을 허용해서 length개를 뽑으려면 product("AEIOU", repeat=length) 처럼 repeat 인자임을 명확하게 적어야합니다.
단순히 product("AEIOU", length)로 작성하면 오류가 발생합니다.
DFS 풀이
그러나 좀 더 출제자의 의도에 부합하는 풀이는 DFS 풀이인 거 같습니다.
왜나면 DFS 탐색 순서가 정확히 사전 순서와 일치하기 때문입니다.
따로 sort 함수로 정렬을 하는 부분없이 좀 더 직관적인 풀이입니다.
vowels = ['A', 'E', 'I', 'O', 'U']
answer = 0
found = False
def dfs(current, word):
global answer, found
if found:
return
if current:
answer += 1
if current == word:
found = True
return
if len(current) == 5:
return
for v in vowels:
dfs(current + v, word)
def solution(word):
dfs('', word)
return answer자리별 가중치 부여 방식
동우 님 풀이 방식인데 정말 생각도 하지못한 획기적인 방법이네요. 연산 횟수가 최대 5밖에 안되는 거의
문제를 풀다보니 거의 탐색 문제는 순열, 조합, 중복순열, 중복조합, 모든 부분집합 찾기 내에서 다 풀리는 거 같습니다. 따라서 위 4가지 라이브러리 사용법과 혹시 모르니 직접 구현하는 방법도 익혀둬야 할 거 같습니다!
🔗 문제 링크
모음사전
LV.2
✔️ 소요된 시간
30분
✨ 수도 코드
민준님이 프로그래머스에 좋은 문제들이 많다고 개인적으로 추천해주셔서, 예전에 프로그래머스에서 문제를 쭉 풀다가 막혀서 백준으로 넘어왔던 문제를 다시 시도해 봤습니다.
문제에서 요구하는 사항은 특정 단어가 A,E,I,O,U로만 사용하는 사전에서 사전순으로 몇 번째에 있는지를 구하는 것입니다.
우선 조금 적어보면서 규칙성을 파악해보려 했습니다.
구조적으로 각 인덱스에서 전에 썼던 구조를 다시 사용하는 경향성이 있는 것 같아서, 재귀함수를 이용한 DFS로 구현하면 괜찮을 것 같다는 생각이 들었습니다.
재귀함수 인자로는 현재 깊이에서 만들어진 string을 전달했고, 기저 조건으로는 문자열의 길이가 5 초과인지, 혹은 체크하려는 문자열과 같은지를 확인하는 조건을 달았습니다.
재귀호출 시에는 현재 문자열 + {A,E,I,O,U} 각각 1개를 붙여 다음 깊이로 내려보내는 식으로 구조를 설계했습니다.
간단한 시행착오를 겪으며 알아낸 주의해야 할 점은, 전역변수로 재귀함수가 호출된 횟수인 count를 조작할 때 함수의 초기 인자가 빈 문자열이라면 그 호출 또한 count가 늘어나기 때문에 변수를 -1에서 시작해야 한다는 점입니다.
📚 새롭게 알게된 내용
예전에 PS를 시작해서 아무것도 몰랐던 때에는 아이디어도 전혀 떠올리지 못해서 풀지 못하고 백준으로 넘어가게 된 계기였던 문제였는데, 지금 읽어보니 쉽게 떠올릴 수 있었고 구현도 쉽게 해낸 것 같아서 그때보단 조금 성장했다는 느낌이 드는 것 같습니다.