• 小明的密码(代码精简版)


    小明的密码

    描述

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

     

    输入格式

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

     

    输出格式

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

    #include <cstdlib>
    #include <cstdio>
    #include  <cstring>
    using namespace std;
    int visited[5][20][9009];// 访问情况
    int dp[5][20][9009];  // M N num num即M-1位的数字
    int num_2[7]= {2,3,5,7,11,13,17};
    int num_3[9]= {2,3,5,7,11,13,17,19,23};
    int num_4[11]= {2,3,5,7,11,13,17,19,23,29,31};  //存储素数
    int N,M,T;
    int delete_head(int num,int m)  //去掉当前数字的首个数字
    {
        int ans;
        if (m==2) return 0;
        if (m==3) ans=num-num/10*10;
        if (m==4) ans=num-num/100*100;
        return ans;
    }
    int divide_num(int num)
    {
        int ans=0;
        while (num>0)
        {
            ans+=num;
            num=num/10;
        }
        return ans;
    }
    int select_num(int k,int sum,int m)
    {
        if (m==2)
        {
            for (int i=0; i<7; i++) if (k+divide_num(sum)==num_2[i]) return 1;
            return 0;
        }
        if (m==3)
        {
            for (int i=0; i<9; i++) if (k+divide_num(sum)==num_3[i])  return 1;
            return 0;
        }
        if (m==4)
        {
            for (int i=0; i<11; i++) if (k+divide_num(sum)==num_4[i]) return 1;
            return 0;
        }
    }
    void work(int m,int n,int num)
    {
        if (n==0)  // n=0直接处理
        {
            visited[m][n][num]=1;
            dp[m][n][num]=1;
        }
        else
        {
            if (!visited[m][n][num])
            {
                visited[m][n][num]=1;
                for (int k=0; k<=9; k++)
                {
                    if (select_num(k,num,m))
                    {
                        int next=delete_head(num,m)*10+k; //next是num的下个状态(去头加尾)
                        if (!visited[m][n-1][next])
                        {
                            work(m,n-1,next);
                        }
                        dp[m][n][num]+=dp[m][n-1][next];
                    }
                }
            }
        }
    }
    
    int Mp(int T){
        int returnNum=1;
        T--;
        while (T--){
            returnNum=returnNum*10;
        }
        return returnNum-1;
    }
    int Mplus(int M){
    int num=1,ans=0,cont=Mp(M);
        for (int i=0;i<=cont;i++){
            work(M,N-M+1,i);
            ans+=dp[M][N-M+1][i];
        }
        printf("%d
    ",ans);
    }
    
    int main()
    {
        memset(visited,0,sizeof(visited));
        memset(dp,0,sizeof(dp));
        scanf("%d",&T);
        while (T--){
            scanf("%d %d",&N,&M);
        if (M==1)
        {
            int ans=1;
            while (N>0)
            {
                ans*=4;
                N--;
            }
            printf("%d
    ",ans);
        }
        else {
            Mplus(M);
        }
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    Java三大特殊类
    静态顺序表and动态顺序表(一)_插入操作
    模拟实现memcpy、memmove函数
    模拟实现strcpy函数
    模拟实现Strlen函数
    数组相关知识总结(一)
    C语言学习总结(二)__操作符
    受控组件 & 非受控组件
    SyntheticEvent
    ReactDOM & DOM Elements
  • 原文地址:https://www.cnblogs.com/Lionel002/p/13339785.html
Copyright © 2020-2023  润新知