题目源地址:k进制数
题目:
问题 1117: K-进制数
时间限制: 1Sec 内存限制: 128MB 提交: 336 解决: 126
题目描述
考虑包含N位数字的K-进制数. 定义一个数有效, 如果其K-进制表示不包含两连续的0.
例:
1010230 是有效的7位数
1000198 无效
0001235 不是7位数, 而是4位数.
给定两个数N和K, 要求计算包含N位数字的有效K-进制数的总数.
假设2 <= K <= 10; 2 <= N; 4 <= N+K <= 18.输入
两个十进制整数N和K
输出
十进制表示的结果
样例输入
2
10
样例输出
90
题目分析:
(1)它是一个首位不为0的K进制数
(2)它不包含连续的两个0
思路:
从题目中我们可知k进制数的含义,其实我们不难发现:一个长度为 i 的k进制数,它的k进制数总数等于他的第 (i-1)位数为0、(i-2)位数不为0的情况加上(i-1)位数不为零的情况!即:f[i] = (f[i-1] + f[i-2])*(k-1)
其实就是 f[i] 也就是 i 位 K 进制数的总数应该等于:"第i-1位为0" 与 "第i-1位不为0的情况" 的和乘以第i位的情况数(1..k-1)
(1)第i-1位为0的情况应该等于i-2位不为0的情况总数,即f[i-2]
(2)第i-1位不为0的情况应该等于f[i-1]
所以:f[i] = (f[i-1] + f[i-2])*(k-1)
从这里我们就可以看出这个题可以用分治算法:
注意:n=1时,其数量就是除了0以外的1~k-1,即(k-1)。 n=2时第1位不取0,后一位可取0~k-1,即(k-1)*k;
写出符合的递归方程:
代码实现:
package com.hsk.raiseExercise;
import java.util.Scanner;
public class K进制数 {
static int k=0;
public static int f(int n){
if(n==1) //问题边界,n==1时,除了0以外的k-1位数都符合
return k-1;
if(n==2)
return (k-1)*k;//问题边界,n==2时,第一位不能取0,所以有k-1中。后一位可取0,有k种
return f(n-1)*(k-1) + f(n-2)*(k-1); //递归求解
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int k1 = scan.nextInt();
k=k1;
System.out.println(f(n));
}
}