반응형

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

 

1759번: 암호 만들기

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

www.acmicpc.net

 

 

💡 암호 만들기

바로 어제 최백준 조교가 방 열쇠를 주머니에 넣은 채 깜빡하고 서울로 가 버리는 황당한 상황에 직면한 조교들은, 702호에 새로운 보안 시스템을 설치하기로 하였다. 이 보안 시스템은 열쇠가 아닌 암호로 동작하게 되어 있는 시스템이다.암호는 서로 다른 L개의 알파벳 소문자들로 구성되며 최소 한 개의 모음(a, e, i, o, u)과 최소 두 개의 자음으로 구성되어 있다고 알려져 있다. 또한 정렬된 문자열을 선호하는 조교들의 성향으로 미루어 보아 암호를 이루는 알파벳이 암호에서 증가하는 순서로 배열되었을 것이라고 추측된다. 즉, abc는 가능성이 있는 암호이지만 bac는 그렇지 않다.새 보안 시스템에서 조교들이 암호로 사용했을 법한 문자의 종류는 C가지가 있다고 한다. 이 알파벳을 입수한 민식, 영식 형제는 조교들의 방에 침투하기 위해 암호를 추측해 보려고 한다. C개의 문자들이 모두 주어졌을 때, 가능성 있는 암호들을 모두 구하는 프로그램을 작성하시오.

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

[출력]
각 줄에 하나씩, 사전식으로 가능성 있는 암호를 모두 출력한다.

 

 

✅ 문제 풀이
  • vector에 C개의 문자를 입력 받은 후, 알파벳 순으로 정렬해준다.
  • des함수는 C개의 각 문자를 포함하는 경우와 포함하지 않는 경우로 재귀 호출된다.
  • 처음에는 빈 문자열로 시작했다가, C개의 문자를 차례로 방문하면서 붙이거나, 붙이지 않도록 한다.
  • 그래서 붙인 문자열이 L개가 되면 res 벡터에 문자열을 넣어두고, des함수를 멈춘다.
  • 그렇지 않다면 des함수를 호출해 붙일 문자를 붙여 넘긴 것과, 붙이지 않고 넘긴 것으로 두번 호출한다. 그리고 현재 가리키는 문자를 cnt로 정의하여 +1해준 값을 넘겨준다.
  • 그리고 des함수가 종료되고 나면, res에 있는 크기가 L인 문자열들을 걸러내야 한다. 문제에서 주어진 빨간 색 조건에 맞도록 한다.
  • 즉 모음이 1개 이상이고, 자음이 2개 이상인지 확인 한다.
  • res 벡터를 순회하면서 각 문자열에 모음과 자음을 count한다. 모음이 1개 이상이고 자음이 2개 이상이면 화면에 출력하도록 하고, 그렇지 않으면 출력하지 않는다.

 

✏ 코드 전문
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>

using namespace std;

int L, C;
vector<string> res;
void des(vector<string> alp, string sum, int cnt) {
	if (sum.length() == L) {
		res.push_back(sum);
		return;
	}
	if (cnt < C) {
		des(alp, sum + alp[cnt], cnt + 1);
		des(alp, sum, cnt + 1);
	}
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	cin >> L >> C;

	vector<string> alp;
	for (int i = 0; i < C; i++) {
		string ch;
		cin >> ch;
		alp.push_back(ch);
	}

	sort(alp.begin(), alp.end());

	des(alp, "", 0);
	
	
	for (int i = 0; i < res.size(); i++) {
		int moem=0;
		int jaem = 0;
		for (int j = 0; j < res[i].length(); j++) {
			if (res[i][j] == 'a' || res[i][j] == 'e' || res[i][j] == 'i' || res[i][j] == 'o' || res[i][j] == 'u') moem++;
			else jaem++;

			if (moem >= 1 && jaem >= 2) {
				cout << res[i] << "\n";
				break;
			}
		}
	}

	return 0;
}
반응형
반응형

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

 

1182번: 부분수열의 합

첫째 줄에 정수의 개수를 나타내는 N과 정수 S가 주어진다. (1 ≤ N ≤ 20, |S| ≤ 1,000,000) 둘째 줄에 N개의 정수가 빈 칸을 사이에 두고 주어진다. 주어지는 정수의 절댓값은 100,000을 넘지 않는다.

www.acmicpc.net

 

 

💡 부분수열의 합
N개의 정수로 이루어진 수열이 있을 때, 크기가 양수인 부분수열 중에서 그 수열의 원소를 다 더한 값이 S가 되는 경우의 수를 구하는 프로그램을 작성하시오.

[입력]
첫째 줄에 정수의 개수를 나타내는 N과 정수 S가 주어진다. (1 ≤ N ≤ 20, |S| ≤ 1,000,000) 둘째 줄에 N개의 정수가 빈 칸을 사이에 두고 주어진다. 주어지는 정수의 절댓값은 100,000을 넘지 않는다.

[출력]
첫째 줄에 합이 S가 되는 부분수열의 개수를 출력한다.

 

부분수열의 개념을 정확히 몰라서 처음에는 연속적인 수열을 생각했는데, 그냥 수열 내 부분집합이라 생각하면 된다.

단, 공집합은 제외한다.

 

 

✅ 문제 풀이
  • 처음에는 visited 배열을 선언하고 방문 여부를 바꾸면서 백트래킹으로 해결하려했으나, 코드가 복잡하고 한눈에 안들어와서 매우 간단한 재귀함수 풀이로 바꾸었다.
  • func(num, sum)라는 함수를 사용할 건데, num은 현재 수열에서 몇개까지 봤는지이고, sum은 수열에서 num번째 수를 포함하거나 포함하지 않은 값이다. 즉 누적 합이다.
  • func()함수 내에서 만약 num이 N이면, 즉 끝까지 다 방문했을경우에, sum이 S와 같으면 answer를 하나 올려준다. 그리고 return을 통해 더이상 재귀가 일어나지 않도록 한다.
  • 그리고 다음 값을 더하지 않는 경우 func(num+1, sum)와 다음 값을 더하는 경우 func(num+1, sum+arr[num])로 두번 호출하여 재귀를 이어나가도록 한다.
  • 그림으로 나타내면 다음과 같다. 그림에서는 예제의 값으로 사용하였다.

수열의 num번째 값을 더한 쪽을 왼쪽, 안더한 쪽을 오른쪽으로 하여 가지치기 형태로 재귀를 호출하게 된다.

보면 맨 오른쪽의 아무것도 더하지 않는 공집합이 포함되어 있음을 알 수 있다.

  • num은 0, sum은 0부터 시작한다. 
  • func(0,0)을 하고 나면 count 된 값이 answer가 된다.
  • 주의할 점은, S가 0인 경우에, 공집합의 0도 count에 포함시켜버리므로, 이런 경우에는 answer를 하나 빼주면 된다. 

 

✏ 코드 전문
#include<iostream>

using namespace std;

int N, S, answer=0;
int *arr;

void func(int num, int sum) {
	if (num == N) {
		if (sum == S) {
			answer++;
		}
		return;
	}
	func(num + 1, sum);
	func(num + 1, sum + arr[num]);
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	cin >> N >> S;

	arr = new int[N];
	for (int i = 0; i < N; i++) {
		cin >> arr[i];
	}
	
	func(0, 0);

	if (S == 0) answer--;

	cout << answer;

	return 0;
}
반응형

+ Recent posts