18025 小明的密码
Posted 谜原
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
以上是关于18025 小明的密码的主要内容,如果未能解决你的问题,请参考以下文章