Sam数【模拟】

Description–

小G最近发现了一种非常有趣的数,他将这种数称之为Sam数。Sam数具有以下特征:相邻两位的数字之差不超过2。小G还将Sam数按位数进行了分类,他将一个k位Sam数称之为k阶Sam数。但不幸的是小G发现他数不清第k阶的Sam数一共有多少个,这个时候机智的他想到了向你求助。


Input–

第一行为一个整数k,含义见题面。

Output–

一行一个整数ans,表示k阶的Sam数的个数。
由于第k阶Sam数非常多,你只需要输出ans mod 1,000,000,007。


Sample Input–

4

Sample Output–

867


说明–

数据规模
对于30%的数据,1 ≤ k ≤ 6。
对于60%的数据,1 ≤ k ≤ 1000。
对于100%的数据,1 ≤ k ≤ 1000000。


解题思路–

看了一下数据,发现好像不能直接判断sim数,那就得制造了(不情愿。。。
第一位(从左到右)可以是1~9
在这里插入图片描述
根据题意,
0的后面可接0,1,2;
1的后面可接0,1,2,3;
2的后面可接0,1,2,3,4;
3的后面可接1,2,3,4,5;
4的后面可接2,3,4,5,6;
5的后面可接3,4,5,6,7;
6的后面可接4,5,6,7,8;
7的后面可接5,6,7,8,9;
8的后面可接6,7,8,9;
9的后面可接7,8,9.

如此反复。。。。。。

有0,无01,02,001,002,0001,0002······


代码–

#include<cstdio>
#include<algorithm>
using namespace std;
int z[10]={3,4,5,5,5,5,5,5,4,3};
const long long N=1000000007;
long long s,ans=10,a[3][15];
long long l,k,t;
void hhh(int t)
{
	a[1][0]=a[2][0];a[1][1]=a[2][1];a[1][2]=a[2][2];a[1][3]=a[2][3];
	a[1][4]=a[2][4];a[1][5]=a[2][5];a[1][6]=a[2][6];a[1][7]=a[2][7];
	a[1][8]=a[2][8];a[1][9]=a[2][9];a[2][0]=0;a[2][1]=0;a[2][2]=0;
	a[2][3]=0;a[2][4]=0;a[2][5]=0;a[2][6]=0;a[2][7]=0;a[2][8]=0;a[2][9]=0;//手动---
	if (t==2) l=1;
	else l=0;
	for (int i=l;i<=9;++i)
	{
		if (i>1)
		    a[2][i-2]=(a[2][i-2]+a[1][i])%N;
		if (i>0) 
			a[2][i-1]=(a[2][i-1]+a[1][i])%N;
		a[2][i]=(a[2][i]+a[1][i])%N;
		a[2][i+1]=(a[2][i+1]+a[1][i])%N;a[2][i+2]=(a[2][i+2]+a[1][i])%N;//制造中······
	}
}
int main()
{
    scanf("%d",&k);
    a[2][1]=1;a[2][2]=1;a[2][3]=1;a[2][4]=1;
	a[2][5]=1;a[2][6]=1;a[2][7]=1;a[2][8]=1;a[2][9]=1;//手动---
    for (int i=2;i<=k;++i)
      hhh(i);
    if (k>1)
    {
    	ans=0;
    	for (int i=0;i<=9;++i)
          ans=(ans+a[1][i]*z[i])%N;
    }
	printf("%lld",ans);
	  
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43654542/article/details/88720181
SAM