935.骑士拨号器 - 力扣

935.骑士拨号器 - 力扣

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

题目:

在这里插入图片描述

示例 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 vector<vector<int>>fromNum = {{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 < 10; i++) dp[1][i] = 1;

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

代码:

暴力求解:

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

# include<iostream>
# include<set>
# include<string>
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<string> answer;
void search(int n, string temp_string, int temp_number, int pos_x, int pos_y){
//	cout<<temp_string<<endl; 
	// 如果达到了边界,就进行存入数据,并且返回。 
	if(temp_number == n){
		answer.insert(temp_string);
//		cout<<temp_string<<endl;
		return ;
	}
	// 如果没有达到边界,就继续进行递归累加
	// 一共有八种方向,每一个方向都进行尝试
	for(int dire = 0;dire < direction_number; dire ++){
		int temp_x = pos_x + x[dire];
		int temp_y = pos_y + y[dire];
		if(temp_x >= min_x && temp_x <= max_x && temp_y >= min_y && temp_y <= max_y){  // 判断是否越界 
			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; cin>>n;
	int n = 14;
	int rows = sizeof(a) / sizeof(a[0]);
	int colums = sizeof(a[0]) / sizeof(a[0][0]);
	// 初始位置可以是任意一个数字的位置
	for(int row = 0;row < rows; row++){
		for (int colum = 0; colum < colums; colum ++){
			if(row == 3 && colum == 0 || row == 3 && colum == 2) continue;
			string num_to_string = to_string(a[row][colum]);
			search(n, num_to_string, 1, row, colum);
		}
	}
	
	cout<<answer.size() % mod<<endl;
	

//	for(int row = 0;row < rows; row++){
//		for (int colum = 0; colum < colums; colum ++){
//			printf("%d ", a[row][colum]);
//		}
//
//	}
	return ;
}

signed main(){
	IOS int t = 1;
	while(t--){
		solve();
	}
	return 0;
} 

动态规划:

调试代码:
#include<iostream>
#include<vector>
using namespace std;
# define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
# define ll long long

const ll mod = 1e9 + 7;
const vector<vector<int>>fromNum = {{4, 6}, {6, 8}, {7, 9}, {4, 8}, {3, 9, 0}, {}, {1, 7, 0}, {2, 6}, {1, 3}, {4, 2}};
void solve(){
//	int n;cin>>n;
	int N = 3131;
	int ans = 0;
	vector<vector<ll>>dp(N + 1, vector<ll>(10, 0));
	// 初始化边界, 一次的电话号码个数 
	for(int i = 0; i < 10;i ++)dp[1][i] = 1;
	// 进行动态规划, 从两次开始 
	for(int n = 2; n<= N;n ++){
		for(int j = 0;j < 10; j++){
			for(int from : fromNum[j]){
				dp[n][j] = (dp[n][j] + dp[n - 1][from]) % mod;
			}
		} 
	}
//	for(int i = 0;i <= N; i++){
//		for(int j = 0;j < 10;j ++){
//			cout<<dp[i][j]<<' ';
//		}
//		cout<<endl;
//	}
	for(int i = 0;i < 10;i ++) ans = (ans + dp.back()[i]) % mod;
	cout<<ans<<endl;
	
	return ;
}


int main(){
	IOS int t = 1;
	while(t--){
		solve();
	}
	return 0;
}
提交代码:
class Solution {
public:
    const long long mod = 1e9 + 7;
    const vector<vector<int>>fromNum = {{4, 6}, {6, 8}, {7, 9}, {4, 8}, {3, 9, 0}, {}, {1, 7, 0}, {2, 6}, {1, 3}, {4, 2}};
    int knightDialer(int N) {
        // int N = 3131;
        int ans = 0;
        vector<vector<long long>>dp(N + 1, vector<long long>(10, 0));
        // 初始化边界, 一次的电话号码个数 
        for(int i = 0; i < 10;i ++)dp[1][i] = 1;
        // 进行动态规划, 从两次开始 
        for(int n = 2; n<= N;n ++){
            for(int j = 0;j < 10; j++){
                for(int from : fromNum[j]){
                    dp[n][j] = (dp[n][j] + dp[n - 1][from]) % mod;
                }
            } 
        }
        for(int i = 0;i < 10;i ++) ans = (ans + dp.back()[i]) % mod;
        
        return ans;
    }
};


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/747846.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

24/06/26(1.1129)动态内存

strtok 字符串分割函数 #include<stdio.h> int main(){ char str[] "this,a sample string."; char* sep ","; char* pch strtok(str, sep); printf("%s\n", pch); while (pch ! NULL){ printf("%s\…

Power BI 占比函数

1&#xff0c;普通层级结构占比 占比1 DIVIDE([sum_qty], CALCULATE([sum_qty],ALLSELECTED(Item[ITEM_CODE]))) //按照line为一个整理展示数据占比2 SWITCH( true(),ISINSCOPE(Item[ITEM_CODE]),DIVIDE([sum_qty], CALCULATE([sum_qty],ALLSELECTED(Item[ITEM_CODE]))), IS…

说说MQ在你项目中的应用(二)商品支付

看了不少关于MQ的文章&#xff0c;也对MQ的作用做了一些总结。通常来说MQ有三大功能&#xff1a;异步处理、系统解耦和流量削峰。但我觉得这些功能本质上都是围绕着异步这个核心来的&#xff0c;只是针对不同的业务场景做了些调整。 现在市面上常用的MQ中间件&#xff0c;如Ra…

Go语言之函数和方法

个人网站&#xff1a; http://hardyfish.top/ 免费书籍分享&#xff1a; 资料链接&#xff1a;https://url81.ctfile.com/d/57345181-61545511-81795b?p3899 访问密码&#xff1a;3899 免费专栏分享&#xff1a; 资料链接&#xff1a;https://url81.ctfile.com/d/57345181-6…

Java进阶-Lambda

Java进阶-Lambda 前言Lambda表达式什么是Lambda表达式初识Lambda表达式Lambda表达式的简单使用Lambda表达式格式分析与传统接口方法实现的比较 理解Lambda表达式函数式编程非纯函数实例纯函数示例函数式编程在Lambda表达式中的体现 闭包闭包与Lambda表达式的示例 类型推导-匿名…

【D3.js in Action 3 精译】1.2.2 可缩放矢量图形(一)

译注 由于 1.2.2 小节介绍 SVG 的篇幅过多&#xff0c;为了方便查阅&#xff0c;后续将分多个小节依次进行翻译。为了确保整个 1.2.2 小节的完整性&#xff0c;特意将上一篇包含的 SVG 小节的内容整理出来重新编排。敬请留意。 1.2.2 SVG - 可缩放矢量图形 可伸缩矢量图形&…

802.11漫游流程简单解析与笔记_Part2_02_wpa_supplicant、cfg80211、nl80211内核与驱动的关系

wpa、cfg80211、nl80211内核与驱动的关系示意图如下&#xff1a; nl80211和cfg80211都是内核定义的标准接口&#xff0c;目的是规范驱动和应用的统一调用&#xff0c;wpa中常出现nl80211就是通过内核的nl80211接口调用对应cfg80211的部分&#xff0c;进而控制驱动收发数据或切换…

实现高效写入:Schemaless 写入性能优化指南

物联网应用常常需要收集大量的数据&#xff0c;用以支持智能控制、业务分析和设备监控等功能。然而&#xff0c;应用逻辑的更新或硬件的调整可能会导致数据采集项频繁变化&#xff0c;这是时序数据库&#xff08;Time Series Database&#xff0c;TSDB&#xff09;面临的一大挑…

排序算法之java语言实现

零、说在前面 近期打算复习java的几种排序算法&#xff0c;我会将这些排序算法的实现代码、个人心得、时间复杂度分析&#xff0c;算法间的对比做成一个系列帖子&#xff0c;这里作为那些帖子的汇总而存在。 这个系列的框架会包含&#xff1a;概念、实现、时间空间复杂度…

50、基于NARX神经网络的磁悬浮建模(matlab)

1、NARX神经网络简介 NARX&#xff08;非线性自回归外部输入&#xff09;神经网络是一种用于非线性建模和预测的神经网络结构。与传统的自回归模型不同&#xff0c;NARX网络可以接收外部输入来影响输出结果&#xff0c;从而更好地捕捉系统的复杂性和非线性特征。 NARX神经网络…

为什么计算机中的无线网络被称为“Wi-Fi”?

在当今信息化社会中&#xff0c;无线网络已经成为我们生活中不可或缺的一部分。无论是家庭、办公室还是公共场所&#xff0c;我们都能享受到便捷的无线互联网连接。而当我们谈及无线网络时&#xff0c;一个经常听到的术语就是“Wi-Fi”。那么&#xff0c;为什么计算机中的无线网…

植物大战僵尸杂交版v2.1最新整合版,附PC端+安卓端+iOS端安装包+修改器+安装教程!

嘿&#xff0c;大家好&#xff0c;我是阿星&#xff0c;今天要跟大家聊聊一款游戏&#xff0c;它不是那种让人眼花缭乱的大制作&#xff0c;也不是那种能让人回味无穷的艺术作品&#xff0c;但它在阿星心里&#xff0c;绝对是神作中的佼佼者。没错&#xff0c;它就是《植物大战…

【windows】win11系统跳过联网和微软账户登录,实现本地账户登录

问题原因&#xff1a;现在市面上销售的品牌笔记本和台式机基本上都预装了正版的Windows S11家族中文版操作系统&#xff0c;联网后系统会自动激活。在win11的版本中&#xff0c;隐藏了关闭跳过连接网络的按钮&#xff0c;默认强制需要注册微软账户登录才能正常使用。 一、跳过…

动态规划——123. 买卖股票的最佳时机 III

目录 1、题目链接 2、题目分析 1.状态表示 2.状态转移方程 3.初始化 4.填表 5.返回值 3、代码解析 1、题目链接 123. 买卖股票的最佳时机 III 2、题目分析 1.状态表示 由题目可知&#xff0c;我们分为两种状态&#xff0c;买入和卖出&#xff0c;又因为只能完成两次交易…

MAC 查看公钥私钥

电脑配置过公钥私钥&#xff0c;现在需要查看&#xff1a; 1、 查看本地是否存在SSH密钥 命令&#xff1a;ls -al ~/.ssh 如果在输出的文件列表中发现id_rsa和id_rsa.pub的存在&#xff0c;证明本地已经存在SSH密钥&#xff0c;请执行第3步 2、 生成SSH密钥 命令&#xff1…

我的3次软考高项通关之旅

1、缘起 初次听说软考是在2022年下半年了&#xff0c;软考的高级分为很多种&#xff0c;我起先想报考高级架构师&#xff0c;但是架构师一年才考一次&#xff0c;如果一次考不过得再准备一年&#xff0c;时间对我来说太长了&#xff0c;于是我决定报考一年考两次的高项。对于国…

【Unity】RPG2D龙城纷争(六)关卡编辑器之角色编辑

更新日期&#xff1a;2024年6月26日。 项目源码&#xff1a;第五章发布&#xff08;正式开始游戏逻辑的章节&#xff09; 索引 简介一、角色编辑模式1.将字段限制为只读2.创建角色&#xff08;刷角色&#xff09;3.预览所有角色4.编辑选中角色属性5.移动角色位置6.移除角色 简介…

Linux OpenGrok搭建

文章目录 一、目的二、环境三、相关概念3.1 OpenGrok3.2 CTags3.3 Tomcat 四、OpenGrok搭建4.1 安装jdk4.2 安装ctags依赖4.3 安装universal-ctags4.3.1 下载universal-ctags4.3.2 编译&&安装universal-ctags 4.4 安装Tomcat4.4.1 下载&&解压Tomcat4.4.2 启动T…

HQChart使用教程30-K线图如何对接第3方数据41-分钟K线叠加股票增量更新

HQChart使用教程30-K线图如何对接第3方数据40-日K叠加股票增量更新 叠加股票叠加分钟K线更新Request 字段说明Data.symbol 协议截图返回json数据结构overlaydata HQChart代码地址交流 叠加股票 示例地址:https://jones2000.github.io/HQChart/webhqchart.demo/samples/kline_i…

泰迪智能科技大数据挖掘企业服务平台典型合作案例介绍

泰迪大数据挖掘企业服务平台 是一款通用的、企业级、智能化的数据分析模型构建与数据应用场景设计工具&#xff0c;能够一体化地完成数据集成、模型构建、模型发布&#xff0c;为数据分析、探索、服务流程提供支撑&#xff0c;提供完整的数据探索、多数据源接入、特征处理、模型…