標籤:
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輸出一個滿足條件的密碼總數
輸入範例
21 12 1
輸出範例
416
這題資料很小,可以直接DFS暴力求解,但是有更好的DP思路。。不過代碼略長dp[i][j][k][z],i表示當前是幾位元,j表示當前這個數的最後一位,k,z分別是倒數二、三位。
假設M=4時.如果j+k+z+a是素數的時候,dp[i-1][k][z][a]可以推出dp[i][j][k][z],也就是dp[i][j][k][z]+=dp[i-1][k][z][a];
這樣一來,我們就可以用暴力的方法求出dp[4][j][k][z],然後遞推上去。時間複雜度是n*10^m
下面是代碼
#include <cstdio>#include <cstring>#include <cmath>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <stack>typedef long long ll;#define X first#define Y second#define mp(a,b) make_pair(a,b)#define pb push_back#define sd(x) scanf("%d",&(x))#define Pi acos(-1.0)#define sf(x) scanf("%lf",&(x))#define ss(x) scanf("%s",(x))#define maxn 1000000#include <ctime> //如果是學校的同學要把這個刪掉,因為學校OJ禁了time標頭檔.const int inf=0x3f3f3f3f;const long long mod=1000000007;using namespace std;int dp[15][10][10][10];long long ans[15][5];bool prime[100];void get_prime(){ prime[0]=prime[1]=1; for(int i=2;i<=40;i++) { if(!prime[i]) { for(int j=i+i;j<=40;j+=i) prime[j]=1; } }}void init(){ ans[0][1]=1; //M=1 for(int i=1;i<=12;i++) ans[i][1]=ans[i-1][1]*4; //M=2 for(int i=0;i<=9;i++) for(int j=0;j<=9;j++) if(!prime[i+j]) dp[2][0][0][i]++; for(int i=3;i<=12;i++) for(int j=0;j<=9;j++) for(int k=0;k<=9;k++) if(!prime[j+k]) dp[i][0][0][j]+=dp[i-1][0][0][k]; for(int i=1;i<=12;i++) for(int j=0;j<=9;j++) ans[i][2]+=dp[i][0][0][j]; //M=3 memset(dp,0,sizeof dp); for(int i=0;i<=9;i++) for(int j=0;j<=9;j++) for(int k=0;k<=9;k++) if(!prime[i+j+k]) dp[3][0][i][j]++; for(int i=4;i<=12;i++) for(int j=0;j<=9;j++) for(int k=0;k<=9;k++) for(int z=0;z<=9;z++) if(!prime[j+k+z]) dp[i][0][j][k]+=dp[i-1][0][k][z]; for(int i=1;i<=12;i++) for(int j=0;j<=9;j++) for(int k=0;k<=9;k++) ans[i][3]+=dp[i][0][j][k]; //M=4 memset(dp,0,sizeof dp); for(int i=0;i<=9;i++) for(int j=0;j<=9;j++) for(int k=0;k<=9;k++) for(int z=0;z<=9;z++) if(!prime[i+j+k+z]) dp[4][i][j][k]++; for(int i=5;i<=12;i++) for(int j=0;j<=9;j++) for(int k=0;k<=9;k++) for(int z=0;z<=9;z++) for(int a=0;a<=9;a++) if(!prime[j+k+z+a]) dp[i][j][k][z]+=dp[i-1][k][z][a]; for(int i=1;i<=12;i++) for(int j=0;j<=9;j++) for(int k=0;k<=9;k++) for(int a=0;a<=9;a++) ans[i][4]+=dp[i][j][k][a];}int main(){ #ifdef local freopen("in","r",stdin); //freopen("out","w",stdout); int _time=clock(); #endif get_prime(); init(); int T; cin>>T; while(T--) { int n,m; cin>>n>>m; cout<<ans[n][m]<<endl; } #ifdef local printf("time: %d\n",int(clock()-_time)); #endif}View Code
scauoj 18025 小明的密碼 數位DP