18025 小明的密码

18025 小明的密码

时间限制:4000MS  内存限制:65535K
提交次数:0 通过次数:0

题型: 编程题   语言: G++;GCC

 

Description

小明的密码由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



 

作者

 admin

  SCAU 小明的密码—深度优先搜索(dfs)。应该说是暴力深搜(700ms过了...题目对时间的限制已经是很水的了...);我的做法是边生成边测试, 是 连续m段的生成。在dfs()函数里加一个参数sum记录前面m-1个密码的总和。   如果当前访问的位置pos是小于m的,则在该位置循环放置0~9,然后进入下一层dfs。如果大于等于m了, 也在该位置循环放置0~9并判断sum+i是否为素数,如果是 则进入下一层dfs,且将参数sum改为sum+i-a[pos-m+1]; 即sum加上当前位置的数字后再减去这m段密码的首位置的数字。  所以,概括的来说就是在不停的维护一个长度为m的区间的数字总和,sum记录最新的m-1个连续数字的和,然后判断当前位置(也就是这个连续m段的最后一个位置)的数字需要为什么时能使这个m段总和为素数。 在进入下一层dfs前,得把这个位置的数字加到sum里去,再减去刚刚得到的这个长度为m的段的首个数字,于是又得到一个m-1段的总和,然后在下一层dfs里判断下个位置为多少时能和这个m-1个数字的和组成素数.....以此递推下去,,,                       感觉这题的解释自己讲的好啰嗦,而且表达的也并不清楚,看代码吧

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <cctype>
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <set>
 9 #include <map>
10 #include <queue>
11 #include <stack>
12 #include <utility>
13 #include <vector>
14 #define ll long long
15 #define inf 0x3f3f3f3f
16 using namespace std;
17 
18 //得出素数表 (素数筛选法)
19 bool prime[56];
20 void get_prime()//m最大为4,所以筛选出前50素数足矣了。
21 {
22     for(int i=0; i<55; i++) //初始化
23         prime[i]=false;
24     for(int i=3; i<55; i+=2) //先将所有奇数标记为true
25         prime[i]=true;
26     prime[1]=false;   prime[2]=true;
27     for(int i=3; i<=sqrt(55); i++)
28         if(prime[i])
29             for(int j=i+i; j<=55; j+=i)
30                 prime[j]=false;
31 }
32 //
33 int a[20];//数组a[]用来存放密码
34 int cnt,n,m;
35 void dfs(int pos,int sum)
36 {
37     if(pos==n) //如果已经到了密码的最后一个位置
38     {
39         for(int i=0; i<10; i++)
40             if(prime[sum+i])
41                 cnt++;
42         return;
43     }
44     if(pos<m) //如果当前检验的密码段还不到m长度
45     {
46         for(int i=0; i<10; i++)
47         {
48             a[pos]=i;
49             dfs(pos+1,sum+i);
50         }
51     }
52     else
53     {
54         for(int i=0; i<10; i++)
55         {
56             if(prime[sum+i])
57             {
58                 a[pos]=i;
59                 dfs(pos+1,sum+i-a[pos-m+1]);
60             }
61         }
62     }
63 }
64 int main()
65 {
66     //freopen("input.txt","r",stdin);
67     get_prime();
68     int t;
69     scanf("%d",&t);
70     while(t--)
71     {
72         scanf("%d%d",&n,&m);
73         cnt=0;
74         dfs(1,0);
75         printf("%d\n",cnt);
76     }
77     return 0;
78 }

 

posted @ 2016-06-02 00:47  爱喝可乐的咖啡  阅读(1453)  评论(1编辑  收藏  举报