학습 정리/👨‍💻 PS Study

[C] 백준 1759번 - 암호 만들기

무딘붓 2022. 7. 8. 23:46

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

 

1759번: 암호 만들기

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

www.acmicpc.net

(21.11.4)

1759번: 암호 만들기 - C언어 풀이

 

[소스코드]

#pragma warning(disable:4996)
#include <stdio.h>
// [baekjoon] 1759번 - 암호 만들기

void makepw(char *origin, char *tmp, int l, int c, int i, int k);
void prt(char *tmp, int c);

int main() {
	int l, c;
	scanf("%d %d", &l, &c);
	char ar[15] = { 0 };
	for (int i = 0; i < c; i++) {		// 알파벳 입력받기
		getchar();
		scanf("%c", &ar[i]);
	}

	for (int i = c - 1; i > 0; i--) {	// 입력받은 알파벳을 정렬
		for (int j = 0; j < i; j++) {
			if (ar[i] < ar[j]) {
				char tmpc = ar[i];
				ar[i] = ar[j];
				ar[j] = tmpc;
			}
		}
	}
	char tmp[16] = { 0 };	
	makepw(ar, tmp, l, c, 0, 0);	
	return 0;
}

void makepw(char *origin, char *tmp, int l, int c, int i, int k) {	// 암호로 사용했을 법한 문자 만들기
	if (i == l) prt(tmp, l);
	else {
		for (int k2 = k; k2 < c; k2++) {
			tmp[i] = origin[k2];
			mk(origin, tmp, l, c, i + 1, k2 + 1);
		}
	}
}

void prt(char *tmp, int c) {	// 최소 한 개의 모음과 두 개의 자음으로 구성되어 있는지 확인하고 출력
	int cnt_a = 0;
	int cnt_b = 0;
	for (int k = 0; k < c; k++) {
		if (tmp[k] == 'a' || tmp[k] == 'e' || tmp[k] == 'i' || tmp[k] == 'o' || tmp[k] == 'u') cnt_a++;
		else cnt_b++;
	}
	if (cnt_a >= 1 && cnt_b >= 2)printf("%s\n", tmp);	
}

서로 다른 C 개의 알파벳 소문자가 주어지고, 주어진 글자에서 L 개를 골라 만드는 단어를 찾는 문제다.​

암호의 조건은
1. 알파벳이 암호에서 증가하는 순서로 배열 ( = 각 글자가 사전 순으로 증가 )
2. 최소 한 개의 모음(a, e, i, o, u)과 최소 두 개의 자음으로 구성
이다.

조건 2의 판별은 간단하니까 결국 조건 1을 만족하는 문자열을 만들 수 있는지를 확인하는 문제라고 할 수 있다.


먼저 입력받은 알파벳들을 이용해서 알파벳이 증가하는 순서로 배열되는 문자열을 만들고 (조건 1),
최소 한 개의 모음과 최소 두 개의 자음으로 구성(조건 2) 되면 출력되는 방법으로 문제를 해결했다.​

조건 1을 만족하기 위해서 먼저 입력받은 알파벳을 정렬하고, 재귀 함수를 사용해서 문자열을 만들었다. 
아직 재귀 함수 사용이 서툴러서 고생했지만 만들면서 많이 배운 것 같아서 좋다.