小明的密码

小明的密码题解

小明的密码

题型: 编程题 语言: 无限制

问题描述

描述小明的密码由N(1<=N<=12)个数字构成,每个数字都可以是0至9中任意一个数字,但小明的密码还有
一个特点就是密码中连续的M(1<=M<=4)个数字的和是质数,现给定M和N,求满足条件的密码共有多少
个?


输入格式

第1行是T,case数量,此后T行,每行两个数,N和M

输出格式

每个case输出一个满足条件的密码总数

输入样例2
1 1
2 1

输出样例4
16


题解

1.简单方法:用欧拉筛先找出质数,然后递归

1
2
3
4
5
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
long v[100]= {0},prime[50]= {0},prin=0,n,m,ans,a[20];
void Euler()
{
v[0]=1; v[1]=1;
long i,j;
for(i=2; i<=100; i++)
{
if(!v[i]) prime[prin++]=i;
for(j=0; j<prin; j++)
{
if(i*prime[j]>100) break;
v[i*prime[j]]=prime[j];
if(!i%prime[j])
break;
}
}
}
void solve(long w)
{
long temp;
if(w==n+1) {ans++; return;}
if(w<m)
for(long i=0; i<=9; i++)
{
a[w]=i;
solve(w+1);
}
else for(long i=0; i<=9; i++)
{
temp=0;
for(long j=m; j>1; j--)
temp+=a[w-j+1];
temp+=i;
if(!v[temp]) {a[w]=i; solve(w+1);}
}
return;
}
main()
{
long i,j,casen;
scanf("%ld",&casen);
Euler();
while(casen--)
{
ans=0;
scanf("%ld%ld",&n,&m);
if(m!=1)
for(i=0; i<=9; i++)
{
a[1]=i;
solve(2);
}
else
{
ans=1;
for(i=1; i<=n; i++)
ans*=4;
}
printf("%ld\n",ans);
}
}

2.用数位dp快速求解

写在最后


其实我们在面对同一道题的时候,往往会有多种解法,在这题里面,因为时间限制给的比较宽松,所以简单的递归就可以解决,当然正解应该是用数位dp。只能说,当你有更简单的方法水过去的时候,不要一开始就码正解。