하루 한 접시
[백준] 1759번: 암호 만들기 [C#]
NaZZU
2024. 5. 13. 23:29
주어진 알파벳들중 적어도 모음 1개, 자음 2개를 포함하는 n길이의 문자열을 사전 순으로 모두 구하는 문제이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
using System.IO;
using System.Text;
using System.Linq;
using System.Reflection.PortableExecutable;
using System.Security.Cryptography;
namespace 연습장
{
internal class Program
{
static void Main(string[] args)
{
using var reader = new StreamReader(Console.OpenStandardInput());
using var print = new StreamWriter(Console.OpenStandardOutput());
_1759_boj boj = new _1759_boj();
boj.boj_1759();
}
}
internal class _1759_boj
{
static StringBuilder sb = new StringBuilder();
static int[] arr;
static string[] input;
static List<string> temp;
static int ja = 0;
static int mo = 0;
public void boj_1759()
{
arr = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);
input = Console.ReadLine().ToLower().Split();
Array.Sort(input);
temp = new List<string>();
makeCombi(0, 0);
if (sb[sb.Length - 1] == '\n')
{
sb.Remove(sb.Length - 1, 1);
}
Console.Write(sb);
} // a c i s t w
public void makeCombi(int depth, int breadth )
{
for (int j = depth + breadth ; j <= arr[1] - (arr[0] - depth); j++)
{
temp.Add(input[j]);
if (temp[temp.Count() - 1] == "a" || temp[temp.Count() - 1] == "e" || temp[temp.Count() - 1] == "i" || temp[temp.Count() - 1] == "o" || temp[temp.Count() - 1] == "u")
mo++;
else
ja++;
if (temp.Count() == arr[0] && (mo >= 1 && ja >= 2))
{
foreach (var _ in temp)
sb.Append(_);
sb.Append('\n');
}
if (temp.Count() < arr[0])
makeCombi(depth + 1, breadth);
if (temp[temp.Count() - 1] == "a" || temp[temp.Count() - 1] == "e" || temp[temp.Count() - 1] == "i" || temp[temp.Count() - 1] == "o" || temp[temp.Count() - 1] == "u")
mo--;
else
ja--;
temp.RemoveAt(temp.Count() - 1);
breadth++;
}
}
}
}
|
cs |
처음 봤을 때엔 쉬운 문제라고 생각이 들었었다. 하지만 막상 문제를 풀어보니 생각보다 복잡한 문제였다.
일단 출력 조건이 문자열을 사전순으로 출력하는 것이었다. 어차피 문자열을 사전순으로 만들면 출력도 사전순으로 될 테니 입력받은 문자열을 정렬해주는 것으로 대신하였다.
문자열을 만드는 함수를 재귀함수로 만드는 것이 꽤나 힘들었다.
첫번째 문자는 a, c. i가 올 수 있고, 두번쨰 문자는 c, i, s가 올 수 있었는데, 시작점은 변동되지만 (첫번째 문자는 0, 1, 2번 인덱스, 두번째 문자는 1, 2, 3번째 인덱스) 종료점은 불변 (첫번째 문자는 2번 인덱스 까지, 두번째 문자는 3번 인덱스 까지) 한 특징을 구현하기 위해 깊이와 너비의 개념을 떠올렸다.
문자열이 완성될때 까지 깊이를 증가시켜준다. 문자열이 완성되면, 이후에는 너비를 증가시켜주며 종료점까지 문자열을 만들어준다.
모든 문자열이 만들어지면, 마지막줄에 있는 빈줄을 삭제시켜 주며 출력을 했다.