[白俊]#1256辞書
質問する
東昊と圭完は212番で文字列を勉強した.金ジンヨン助教は、東昊と圭完に特別課題を与えた.特別な課題は,特殊な文字列からなる辞書の作成である.辞書に収録されているすべての文字列は,N個の「a」とM個の「z」からなる.しかも他の文字はありません.辞書にはアルファベット順に収録されている.
圭完は辞書を完成したが、東昊は辞書を完成しなかった.自分の課題を達成するために、東昊は圭完の辞書をこっそり参考にすることにした.東昊は圭がいないうちに辞書をこっそり見ようとしたので、文字列は1つしか見つからなかった.
NとMが与えられた場合、葵婉の辞書からK番目の文字列が何であるかを見つけるプログラムを作成します.
入力
1行目はN,M,Kの順に与えられる.NおよびMは100以下の自然数であり、Kは10000000以下の自然数である.
しゅつりょく
1行目は葵婉の辞書からK番目の文字列を出力します.圭完の辞書の文字列数がKより小さい場合、-1が出力されます.
入力例1
2 2 2
サンプル出力1
azaz
に答える
この問題はダイナミックプログラミングで解決できる.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
static StringBuilder sb;
static long[][] dp;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] input = br.readLine().split(" ");
int N = Integer.parseInt(input[0]);
int M = Integer.parseInt(input[1]);
int K = Integer.parseInt(input[2]);
dp = new long[N+2][M+2];
for(int i=0; i<=N; i++)
dp[i][0] = 1;
for(int j=0; j<=M; j++)
dp[0][j] = 1;
dp[1][1] = 2; //dp 배열 전처리
for(int i=1; i<=N; i++) {
for(int j=1; j<=M; j++) {
dp[i+1][j] = Math.min(dp[i][j]*(i+j+1)/(i+1), 1000000000); //조합을 이용해서 가능한 경우의수 구하기
dp[i][j+1] = Math.min(dp[i][j]*(i+j+1)/(j+1), 1000000000);
}
}
if(dp[N][M]<K)
System.out.println(-1);
else {
sb = new StringBuilder();
make_string(N, M, K);
System.out.println(sb);
}
}
public static void make_string(int n, int m, long k) { //정답 단어 찾기
if(n==0) {
sb.append("z".repeat(Math.max(0, m)));
return;
}
if(m==0) {
sb.append("a".repeat(Math.max(0, n)));
return;
}
if(dp[n-1][m]>=k) {
sb.append('a');
make_string(n-1, m, k);
}
else {
sb.append('z');
make_string(n, m-1, k-dp[n-1][m]);
}
}
}
Reference
この問題について([白俊]#1256辞書), 我々は、より多くの情報をここで見つけました https://velog.io/@pss407/백준1256-사전テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol