935.骑士拨号器 - 力扣

06-27 1675阅读

935.骑士拨号器 - 力扣

题目链接:935. 骑士拨号器 - 力扣(LeetCode)

题目:

935.骑士拨号器 - 力扣

示例 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
解释:注意取模

题解:

题目大意:给定一个电话垫,不同数字之间的移动只能是L形状的路线(L可以旋转),并且只能在数字之间移动,求出长度为n的不同电话号码有多少个?

读完题目之后,一个很简单的思路就是模拟,使用暴力的方式来模拟这一过程,最初我是用的是深度优先搜索算法进行暴力求解,但是回出现栈溢出的情况,在输入N = 3131的时候,电脑内存爆满,导致电脑卡死,而后重启得以恢复。因此需要想出一个更加高效的方法,另一个思路就是——动态规划算法,我们可以定义dp[i][j],表示长度为i终点为数字j的电话号码个数,由于每一个数字能移动到其他数字的个数是有限的,我们可以将其列举出来:

终点数字起点数字
04, 6
16, 8
27, 9
34, 8
43, 9, 0
5
61, 7, 0
72, 6
81, 3
94, 2

可以发现只有数字5移动到其他数字上,并且其他数字也不能移动到数字5上,因此我们可以设置一个vector数组,将其都存储进去,然后在循环的时候进行遍历这个数组,表示每个值能从那个位置移动而来,如果每一个数字能移动其他数字上,那么反过来也是成立的。

const vectorfromNum = {{4, 6}, {6, 8}, {7, 9}, {4, 8}, {3, 9, 0}, {}, {1, 7, 0}, {2, 6}, {1, 3}, {4, 2}};

初始化数组,如果电话号码的长度为1,那么每一个数字都只不能移动,所以长度为1的每一个数字的值都为1。即:for(int i = 0; i

进行动态规划结束后,我们得到的是以每一个数字结尾的长度为n的电话号码个数,只需要将长度为N的每一个数字结尾的电话号码个数进行累加即可得到最终的答案(注意:还要进行取余)。

代码:

暴力求解:

该代码不能使用,会栈溢出,如果使用的话n的值不要超过17,如果超过17,就是不会使内存爆满,也会有漫长的等待时间。

# include
# include
# include
using namespace std;
# define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
# define ll long long
const ll mod = 10e9 + 7;
// 定义工具 
int x[8] = {2, 2, -2, -2, 1, -1, 1, -1};  // 左右 
int y[8] = {-1, 1, -1, 1, -2, -2, 2, 2};  // 上下 
int direction_number = sizeof(x) / sizeof(x[0]);
// 边界
int min_x = 0, min_y = 0;
int max_x = 2, max_y = 3; 
int a[][3] = {
	{1, 2, 3},
	{4, 5, 6},
	{7, 8, 9},
	{-1, 0, -1}
};
set answer;
void search(int n, string temp_string, int temp_number, int pos_x, int pos_y){
//	cout
		answer.insert(temp_string);
//		cout
		int temp_x = pos_x + x[dire];
		int temp_y = pos_y + y[dire];
		if(temp_x = min_x && temp_x   // 判断是否越界 
			if(a[temp_x][temp_y] == -1) continue;  		// 只能遍历到数字
			string num_to_string = to_string(a[temp_x][temp_y]);
			search(n, temp_string + num_to_string, temp_number + 1, temp_x, temp_y);
		}
	}
	
	return ;
}
void solve(){
//	int n; cinn;
	int n = 14;
	int rows = sizeof(a) / sizeof(a[0]);
	int colums = sizeof(a[0]) / sizeof(a[0][0]);
	// 初始位置可以是任意一个数字的位置
	for(int row = 0;row 
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]