본문으로 바로가기

1759 암호 만들기

category ps/브루트 포스 2021. 9. 4. 23:49

암호 만들기 (1759)

 

풀이코드

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
using namespace std;
// 1759 암호 만들기

int L, C;

vector<char> letters;
bool used[15];
string collection = "aeiou";
// 재귀 : "위치"에 어느 알파벳이 들어가는지 기준으로
void solve(int count, int index){
	// 기저사례 : 길이가 L 과 같아지면
	if(count == L){
		string tmp;
		for(int i = 0; i < C; i++){
			// 추정 pw 구현
			if(used[i]){
				tmp.push_back(letters[i]);
			}
		}
		// 기저사례 : 모음이 하나 이상, 자음이 2개 이상이라면
		int collectionCount = 0;
		for(int i = 0; i < 5; i++){
			for(int j = 0; j < L; j++){
				if(collection[i] == tmp[j])
					collectionCount++;
			}
		}
		
		if(collectionCount >= 1 && L - collectionCount >= 2){
			cout << tmp << '\n';
		}
	}
	
	for(int i = index; i < C; i++){
		used[i] = true;
		solve(count + 1, i + 1);
		used[i] = false;
	}
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr); 
	cout.tie(nullptr); 
	
	cin >> L >> C;
	
	for(int i = 0; i < C; i++){
		char tmp;
		cin >> tmp;
		letters.push_back(tmp);
	}
	sort(letters.begin(), letters.end());
	fill_n(used, 15, false);
	
	solve(0, 0);
}

 

해설


적용한 레시피 / 방법론 + 접근법

풀이

1. 브루트 포스가 가능할까?

- '오름차순' 이라는 조건이 붙었기 때문에 경우의 수가 많이 줄어들어 가능하다고 생각했다. 오름차순으로 정렬하여 모든 경우의 수를 따져보면 15개의 알파벳은 절대 1억의 경우의 수를 만들 수 없다.

2. 문제의 조건을 기저사례로

- 오름차순 : input 을 오름차순으로 아예 정렬해버림

- 길이가 L : 기저사례에 추가

- 최소 1개의 모음, 최소 2개의 자음을 만족해야함 : 2번째 기저사례를 통과한다면, 검사한다.

3. 각 위치에 사용할 알파벳을 정하는 것으로 ? 알파벳을 사용하느냐 마느냐로 ?

- 오름차순으로 미리 배열을 정렬해두었기에 둘 다 비슷하다고 생각하였다. 다만, 쓴 문자를 저장하는 것을 push_back 하여 한다면 계산 복잡도가 증가하기에, 사용했다는 정보만을 used 배열에 저장해두었다가 마지막에만 push_back 하였다.

아쉬웠던 부분 / 오답 원인 / 개선해야 할 점

- 처음으로, 깔끔하게 구현했고, 한번에 맞았다. 노트에 생각을 정리하여 알고리즘의 전체적인 흐름과 기저사례를 설정 하고 풀이에 돌입하는 것이 더욱 중요하다는 것을 느꼈다.

- 재귀를 조금 깨우친 느낌이다. 하지만, 메모이제이션에 대해서 기억이 흐릿해지는 것 같아 아쉽다. 종만북에 대한 아쉬움.. 기본을 더 쌓고 나중에 해보면 될 것이다.

반응형

'ps > 브루트 포스' 카테고리의 다른 글

[백트래킹] [비트마스크]14889 스타트와 링크  (0) 2021.09.05
14501 퇴사  (0) 2021.09.05
9095 1,2,3 더하기 +  (0) 2021.09.04
NM과 K (1) 18290  (0) 2021.08.28
15652 N과 M (4)  (0) 2021.08.28