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;
}
posted @ 2012-04-30 11:30  书山有路,学海无涯  阅读(181)  评论(0编辑  收藏  举报