Seren dev's blog
article thumbnail

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

 

1759번: 암호 만들기

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

www.acmicpc.net

풀이

문제를 보고 조합을 이용해야겠다는 생각이 들었다.

암호에는 알파벳을 중복하여 사용할 수 없고, 암호를 이루는 알파벳이 증가하는 순서로 배열되어야 한다.

즉, 입력받는 C개의 문자를 배열에 저장하여 알파벳 순으로 정렬하고, 배열 인덱스(0 ~ C-1)의 모든 조합의 경우의 수를 구하면, 가능성 있는 암호의 모든 경우를 구할 수 있다.

조합은 DFS로 구현한다.

 

조합을 구현하는 기본 틀은 다음과 같다.

백준 15650 N과 M (2)

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

import java.io.*;
import java.util.*;

public class Main {

    static int n, m;
    static int[] comb;
    static StringBuilder sb = new StringBuilder();

    static public void combination(int L, int start) {
        if (L == m) {
            for (int i : comb)
                sb.append(i + " ");
            sb.append("\n");
        }
        else {
            for (int i = start; i <= n; i++) {
                comb[L] = i;
                combination(L+1, i+1);
            }
        }
    }

    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        n = Integer.parseInt(st.nextToken());
        m = Integer.parseInt(st.nextToken());

        comb = new int[m];

        combination(0, 1);
        System.out.println(sb);

    }
}

참고: JAVA 순열, 중복 순열, 조합, 중복 조합 구현

 

주의할 점

"암호는 서로 다른 L개의 알파벳 소문자들로 구성되며 최소 한 개의 모음(a, e, i, o, u)과 최소 두 개의 자음으로 구성되어 있다고 알려져 있다."

조합으로 구한 완성된 암호에서 모음의 개수가 1개 이상이어야 하고, 자음의 개수가 2개 이상인지 체크해줘야 한다.

코드

import java.io.*;
import java.util.*;

public class Main {
	
	static StringBuilder sb = new StringBuilder();
	static String[] word;
	static int[] comb;
	static int L, C;
	
	public static boolean check(String str) {
		if (str.equals("a") || str.equals("e") || str.equals("i") || str.equals("o") || str.equals("u"))
			return true;
		else return false;
	}
	
	public static void combination(int idx, int start) {
		if (idx == L) {
			StringBuilder tmp = new StringBuilder();
			
			int cnt = 0; // 모음의 개수
			
			for (int n : comb) {
				tmp.append(word[n]);
				
				if (check(word[n]))
					cnt++;
			}
			
			if (cnt >= 1 && L-cnt >= 2)
				sb.append(tmp+"\n");
			return;
		}
		
		for (int i = start; i < C; i++) {
			comb[idx] = i;
			combination(idx+1, i+1);
		}
	}
	
	
	public static void main(String[] args) throws IOException {
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		StringTokenizer st = new StringTokenizer(br.readLine());
		L = Integer.parseInt(st.nextToken());
		C = Integer.parseInt(st.nextToken());
		word = new String[C];
		comb = new int[L];
		
		st = new StringTokenizer(br.readLine());
		for (int i = 0; i < C ; i++) {
			word[i] = st.nextToken();
		}
		Arrays.sort(word);
		
		combination(0, 0);
		
		System.out.println(sb);
	}
	
}
728x90
profile

Seren dev's blog

@Seren dev

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!