zoukankan      html  css  js  c++  java
  • 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
    ",cnt);
    76     }
    77     return 0;
    78 }
  • 相关阅读:
    DRBD试用手记
    hibernate get load difference
    4招将PPT文本转换成Doc文本
    about lucene merepolicy
    关于Lucene索引合并解决方法
    网站优化工具帮助
    A/B Experiments with Google Website Optimizer
    about lucene grouping and facet history
    Spring IDE 1.2.4发布
    HTML meta refresh 刷新与跳转(重定向)页面
  • 原文地址:https://www.cnblogs.com/geek1116/p/5551625.html
Copyright © 2011-2022 走看看