开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第14天,点击查看活动详情
[传智杯 #3 初赛] 运气
题目背景
YYH Land(Yoauld,Youthful & Happy Land) 是位于炽蓝仙野的一片神奇的国度,那里的人们过着无拘无束的的快乐生活。
题目描述
哈兰·斯威提是 YYH Land 远近闻名的注铅骰子爱好者。有一天他碰到了这么一个问题:
你有一枚 个面的骰子,分别写了 ,每一面朝上的概率是均等的。
现在哈兰想知道,如果他投掷 次,并且将结果按顺序写在纸上成为一个数。(比如说如果哈兰扔了 次,分别是 ,那么他最后得到的数就是 )他现在想知道这个数是 的倍数的可能情况有多少种,其中 是一个特定的数。
由于这个方案数可能会很大,所以请你输出结果对 取模的结果。
输入格式
一行两个整数 ,意义如题所示。
输出格式
一行一个整数,表示答案。
样例 #1
样例输入 #1
2 11
样例输出 #1
6
提示
样例解释
在投掷两次骰子总共 种可能中,只有 是符合条件的。所以答案是 。
数据规模与约定
对于 的数据,满足 分别为 ;
对于另外 的数据,满足 ;
对于 的数据,满足 ;
思路分析
- 看到是一个排列问题,首先想到的就是深度暴搜(dfs)
- 接着就是看可行性,数据不是很大,也就是O(6^n),那么dfs暴搜是可行的
- 暴搜解决:
- dfs模板退出或者是结束条件就是次数到达结尾,判断是否可以被k整除
- 是的话就加一
- 不是的话就不管
- 然后按照树形的遍历,注意循环次数应该是6次,对应骰子的六面
- dfs模板退出或者是结束条件就是次数到达结尾,判断是否可以被k整除
- 输出的时候要注意mod(1e9+7)
图像理解
图像分为暴搜层和结果判断层
- 暴搜层就是不断的dfs向下循环判断
- 结果层就是到了树的底端,得到暴搜的一个结果,判断是否符合条件
代码呈现
#include<iostream>
using namespace std;
typedef long long LL;
const LL MOD = 1e9 + 7;
LL res;
int n, k;
void dfs(LL sum, int cnt) {//sum代表当前数的和,s代表剩余次数
if (cnt == 0) {
if (sum % k == 0)
res++;
return;
}
for (int i = 1; i <= 6; i++)
dfs(sum * 10 + i, cnt - 1);
}
int main()
{
cin >> n >> k;
dfs(0, n);
cout << res % MOD;
return 0;
}
PS:初赛涉及到了dfs,说不定哪天给来个图论那就有意思了~