多多鸡打算造一本自己的电子字典,里面的所有单词都只由a和b组成。
每个单词的组成里a的数量不能超过N个且b的数量不能超过M个。
多多鸡的幸运数字是K,它打算把所有满足条件的单词里的字典序第K小的单词找出来,作为字典的封面。
共一行,三个整数N, M, K。(0 < N, M < 50, 0 < K < 1,000,000,000,000,000)
共一行,为字典序第K小的单词。
2 1 4
ab
满足条件的单词里,按照字典序从小到大排列的结果是
a
aa
aab
ab
aba
b
ba
baa
对于40%的数据:0 < K < 100,000
对于100%的数据:0 < K < 1,000,000,000,000,000
题目保证第K小的单词一定存在
import java.util.Scanner;
import java.util.Arrays;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
static int n, m;
static long k;
static StringBuffer path = new StringBuffer();
static long [][] dist = new long [55][55];
static void dfs(int da, int db) {
if (dist[n - da][m - db] != -1) {
if (k - dist[n-da][m-db] > 0) {
k -= dist[n-da][m-db];
return;
}
}
long cnt = k;
k --;
if (k == 0) {
System.out.println(path);
return;
}
if (k < 0) return;
if (da < n) {
path.append("a");
dfs(da + 1, db);
path.deleteCharAt(da + db);
}
if (db < m) {
path.append("b");
dfs(da, db + 1);
path.deleteCharAt(da + db);
}
cnt -= k; // 统计子节点个数(包括自身)
dist[n-da][m-db] = cnt;
}
static void problem2020_5() {
Scanner scanner = new Scanner(System.in);
n = scanner.nextInt();
m = scanner.nextInt();
k = scanner.nextLong() + 1;
for (int i = 0; i < dist[0].length; i ++ ) {
Arrays.fill(dist[i], -1L);
}
dfs(0, 0);
}
public static void main(String[] args) {
problem2020_5();
}
}
dfs,排除等效冗余优化可以ac