Timus 1586

想一想知道n-1位的结果,如何得到n位的结果呢?假如我们知道n-1的后两位再枚举第n位的数字,不就得到n位的结果了吗?

我们用res[n][i][j]表示n位最后两位是i和j;

Res[i][j][k]=∑res[i-1][l][j];(其中100*l+10*j+k 是素数)

我们还可以优化一下,因为最后一位只有可能是1、3、7、9。所以可以将k和j所在的循环的长度改为4。

#include<iostream>

#include<cstdio>

#include<cstring>

#include<cmath>

using namespace std;

int res[10001][10][10],flag[1000],b[4]={1,3,7,9};

int IsPrime(int w)

{

    int i,k;

    k=sqrt(w*1.0);

    for(i=2;i<=k;i++)

        if(w%i==0) return 0;

    return 1;

}

int main()

{

    int i,j,k,n,w,l,sum;

    for(i=1;i<10;i++)

        for(j=0;j<10;j++)

            for(k=0;k<4;k++)

            {

                w=i*100+j*10+b[k];

                if(IsPrime(w))

                {

                    flag[w]=1;

                    res[3][j][b[k]]++;

                }

            }

    for(i=1;i<10001;i++)

        for(j=0;j<4;j++)

            for(k=0;k<4;k++)

                for(l=0;l<10;l++)

                    if(flag[100*l+10*b[j]+b[k]])

                    {

                        res[i][b[j]][b[k]]+=res[i-1][l][b[j]];

                        res[i][b[j]][b[k]]%=1000000009;

                    }

                    sum=0;

                    while(scanf("%d",&n)!=EOF)

                    {

                        for(i=0;i<10;i++)

                            for(j=0;j<10;j++)

                            {

                                sum+=res[n][i][j];

                                sum%=1000000009;

                            }

                        printf("%d\n",sum);

                    }

                    return 0;

}

你可能感兴趣的:(IM)