935. 骑士拨号器
象棋骑士有一个独特的移动方式,它可以垂直移动两个方格,水平移动一个方格,或者水平移动两个方格,垂直移动一个方格(两者都形成一个 L 的形状)。
象棋骑士可能的移动方式如下图所示:
我们有一个象棋骑士和一个电话垫,如下所示,骑士只能站在一个数字单元格上(即蓝色单元格)。
给定一个整数 n,返回我们可以拨多少个长度为 n 的不同电话号码。
你可以将骑士放置在任何数字单元格上,然后你应该执行 n - 1 次移动来获得长度为 n 的号码。所有的跳跃应该是有效的骑士跳跃。
因为答案可能很大,所以输出答案模 109 + 7.
示例 1:
输入:n = 1
输出:10
解释:我们需要拨一个长度为1的数字,所以把骑士放在10个单元格中的任何一个数字单元格上都能满足条件。
示例 2:
输入:n = 2
输出:20
解释:我们可以拨打的所有有效号码为[04, 06, 16, 18, 27, 29, 34, 38, 40, 43, 49, 60, 61, 67, 72, 76, 81, 83, 92, 94]
示例 3:
输入:n = 3131
输出:136006598
解释:注意取模
这题c语言题解只有一个,还是不错的一个学习材料,感兴趣的可以看看:
int knightDialer(int n){
int numssize[10]={2,2,2,2,3,0,3,2,2,2};
int nums[10][3]={{4,6},{6,8},{7,9},{4,8},{3,9,0},
{},{1,7,0},{2,6},{1,3},{2,4}};
int dp[n+1][10];
for(int i=0;i<10;i++){
dp[0][i]=0;
}
for(int i=0;i<10;i++){
dp[1][i]=1;
}
for(int i=2;i<=n;i++){
for(int j=0;j<10;j++){
dp[i][j]=0;
for(int k=0;k<numssize[j];k++){
dp[i][j]=dp[i][j]+dp[i-1][nums[j][k]];
dp[i][j]= dp[i][j]%1000000007;
}
}
}
int sum=0;
for(int i=0;i<10;i++){
// printf("%d ",dp[n][i]);
sum=sum+dp[n][i];
sum=sum%1000000007;
}
return sum%1000000007;
}