蓝桥杯练习题——K好数

题目描述:

如果一个自然数N的K进制表示中任意的相邻的两位都不是相邻的数字,那么我们就说这个数是K好数。求L位K进制数中K好数的数目。例如K = 4,L = 2的时候,所有K好数为11、13、20、22、30、31、33 共7个。由于这个数目很大,请你输出它对1000000007取模后的值。

输入格式
输入包含两个正整数,K和L。

输出格式
输出一个整数,表示答案对1000000007取模后的值。

输入样例:

4 2

输出样例:

7

解析:

满足任意相邻两位都不是相邻的数字叫做K好数,即相邻两位数字差值的绝对值不等于1,每一位存在取0 ~ K - 1的任何一个值的可能性(最高位不能取0),因此考虑枚举每一位取0 ~ K - 1的情况。建立如下的二维vector记录第 i 位以 j 结尾情况下的K好数的个数:

vector<vecotr<int> > v(L, vector<int> (K, 0)); // 第一维表示第几位, 第二维表示该位的数字

以第一位表示最高位,不能取0,因此初始条件为:

for (int j = 1; j < K; ++j) {
	v[0][j] = 1;
}

依次往后枚举第 i 位取 j 的情况,同时枚举前一位的取值的情况,构成递推关系:

for (int i = 1; i < L; ++i) {
	for (int j = 0; j < K; ++j) {
		for (int k = 0; k < K; ++k) {
			if (abs(k - j) != 1) { //前一位为k,后一位为j,不相邻则加上上一位的个数
				v[i][j] += v[i - 1][k];
				v[i][j] %= MOD;
			}
		}
	}
}

示意图:

代码实现:

#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
const int MOD = 1000000007;

int main() {
	int K, L;
	cin >> K >> L;
	vector<vector<int> > v(L, vector<int> (K, 0));
	if (K == 1)
		cout << 0;
	else {
		for (int j = 1; j < K; ++j) {
			v[0][j] = 1;
		}
		for (int i = 1; i < L; ++i) {
			for (int j = 0; j < K; ++j) {
				for (int k = 0; k < K; ++k) {
					if (abs(k - j) != 1) {
						v[i][j] += v[i - 1][k];
						v[i][j] %= MOD;
					}
				}
			}
		}
		int ans = 0;
		for (int j = 0; j < K; ++j) {
			ans += v[L - 1][j];
			ans %= MOD;
		}
		cout << ans;
	}
	return 0;
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值