时间限制: 1Sec 内存限制: 128MB
题目描述
考虑包含N位数字的K-进制数. 定义一个数有效, 如果其K-进制表示不包含两连续的0.
考虑包含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
题目解析
这道题我们采用递推形式来一步一步得出答案
考虑n位数k进制
我们定义res_0,res_1两个变量
首先考虑第一层,只有两位数时:
①第一位数字是非零,那么可以取得的结果是res_1=(k-1)k,这几个数字对于两位数字来说都是合理的。
②第一位数字是零时,第二位取得是合理数字,res_0=k-1,就是01、02
03、04、05、06、07、08、09,这里记录res_0的作用一方面是记录了n为1时的数字总数,二是为了参与递推
此时res_0已经保存了n=1时的答案,所以不需要单另分析n=1的情形
接下来考虑第二层,n=3时
①我们需要一个变量来保存res_1,因为这个代表了n=2时数字的数目,需要之后赋值给res_0
②res_1更新为(k-1)*(res_0+res_1),res_1很好理解把,因为res_1本身已经是合法数字了,前面再添加一位数,就变成了(k-1)*res_1位合法数字了,但这些合法数字缺少倒数第二位为0的合法数字,所以我们还需要(k-1)res_0,这里res_0这些数字开头都是0,本身不合法,但是res_0后的数字都合法,前面再加一个非零数字,自然也合法,所以总的就是(k-1)(res_0+res_1)
③res_0=temp,把①中说的中间变量赋值给res_0
代码如下
#include<iostream>
#include<cstring>
#include<algorithm>
#include<math.h>
using namespace std;
int main(){
int n,k;
while(scanf("%d%d",&n,&k)!=EOF){
int res_0=k-1;
int res_1=(k-1)*k;
for(int i=1;i<n;i++){
int temp=res_1;
res_1=(k-1)*(res_0+res_1);
res_0=temp;
}
printf("%d\n",res_0);
}
return 0;
}