C#,电话数字键盘问题(Mobile Numeric Keypad problem)的算法与源代码

1 电话数字键盘问题

提供移动数字键盘。您只能按向上、向左、向右或向下至当前按钮的按钮。不允许您按最下面一行的角点按钮(即.*和#)。


移动键盘

给定一个数N,找出给定长度的可能数。

示例:

对于N=1,可能的数字数为10(0、1、2、3、…、9)

对于N=2,可能的数字数为36

可能的数字:00、08、11、12、14、22、21、23、25等等。

如果我们从0开始,有效数字将是00、08(计数:2)

如果我们从1开始,有效数字将是11、12、14(计数:3)

如果我们从2开始,有效数字将是22、21、23、25(计数:4)

如果我们从3开始,有效数字将是33、32、36(计数:3)

如果我们从4开始,有效数字将是44,41,45,47(计数:4)

如果我们从5开始,有效数字将是55,54,52,56,58(计数:5)

………………………………

………………………………

我们需要打印可能的数字。

推荐做法

移动数字键盘

试试看!

N=1是普通情况,可能的数字数为10(0,1,2,3,…,9)

对于N>1,我们需要从某个按钮开始,然后移动到四个方向(向上、向左、向右或向下)中的任何一个,该方向指向有效的按钮(不应转到*、#)。继续这样做,直到获得N个长度编号(深度优先遍历)。

递归解决方案:

移动键盘是4X3的矩形网格(4行3列)

假设Count(i,j,N)表示从位置(i,j)开始的N个长度数字的计数

如果N=1 ,计数(i,j,N)=10

其他的 Count(i,j,N)=所有Count(r,c,N-1)之和,其中(r,c)是新的

长度1从当前有效移动后的位置

位置(i,j)

下面是上述公式的三种实现代码。

2 源代码

using System;
using System.Collections;
using System.Collections.Generic;namespace Legalsoft.Truffer.Algorithm
{public static partial class Algorithm_Gallery{#region 算法1private static int MNKP_Solve_Utility(char[,] keypad, int i, int j, int n){if (keypad == null || n <= 0){return 0;}if (n == 1){return 1;}int[] row = { 0, 0, -1, 0, 1 };int[] col  = { 0, -1, 0, 1, 0 };int totalCount = 0;for (int move = 0; move < 5; move++){int ro = i + row[move];int co = j + col[move];if (ro >= 0 && ro <= 3 && co >= 0 && co <= 2 && keypad[ro, co] != '*' && keypad[ro, co] != '#'){totalCount += MNKP_Solve_Utility(keypad, ro, co, n - 1);}}return totalCount;}public static int MNKP_Solve(char[,] keypad, int n){if (keypad == null || n <= 0){return 0;}if (n == 1){return 10;}int totalCount = 0;for (int i = 0; i < 4; i++) {for (int j = 0; j < 3; j++) {if (keypad[i, j] != '*' && keypad[i, j] != '#'){totalCount += MNKP_Solve_Utility(keypad, i, j, n);}}}return totalCount;}#endregion#region 算法2public static int MNKP_Solve_2th(char[,] keypad, int n){if (keypad == null || n <= 0){return 0;}if (n == 1){return 10;}int[] row = { 0, 0, -1, 0, 1 };int[] col = { 0, -1, 0, 1, 0 };int[,] count = new int[10, n + 1];for (int i = 0; i < 10; i++){count[i, 0] = 0;count[i, 1] = 1;}for (int k = 2; k <= n; k++){for (int i = 0; i < 4; i++) {for (int j = 0; j < 3; j++) {if (keypad[i, j] != '*' && keypad[i, j] != '#'){int num = keypad[i, j] - '0';count[num, k] = 0;for (int move = 0; move < 5; move++){int ro = i + row[move];int co = j + col[move];if (ro >= 0 && ro <= 3 && co >= 0 && co <= 2 && keypad[ro, co] != '*' && keypad[ro, co] != '#'){int nextNum = keypad[ro, co] - '0';count[num, k] += count[nextNum, k - 1];}}}}}}int totalCount = 0;for (int i = 0; i < 10; i++){totalCount += count[i, n];}return totalCount;}#endregion#region 算法3public static int MNTP_Solve_3th(char[,] keypad, int n){if (keypad == null || n <= 0){return 0;}if (n == 1){return 10;}int[] odd = new int[10];int[] even = new int[10];int useOdd = 0;for (int i = 0; i < 10; i++){odd[i] = 1;}for (int j = 2; j <= n; j++){useOdd = 1 - useOdd;if (useOdd == 1){even[0] = odd[0] + odd[8];even[1] = odd[1] + odd[2] + odd[4];even[2] = odd[2] + odd[1] + odd[3] + odd[5];even[3] = odd[3] + odd[2] + odd[6];even[4] = odd[4] + odd[1] + odd[5] + odd[7];even[5] = odd[5] + odd[2] + odd[4] + odd[8] + odd[6];even[6] = odd[6] + odd[3] + odd[5] + odd[9];even[7] = odd[7] + odd[4] + odd[8];even[8] = odd[8] + odd[0] + odd[5] + odd[7] + odd[9];even[9] = odd[9] + odd[6] + odd[8];}else{odd[0] = even[0] + even[8];odd[1] = even[1] + even[2] + even[4];odd[2] = even[2] + even[1] + even[3] + even[5];odd[3] = even[3] + even[2] + even[6];odd[4] = even[4] + even[1] + even[5] + even[7];odd[5] = even[5] + even[2] + even[4] + even[8] + even[6];odd[6] = even[6] + even[3] + even[5] + even[9];odd[7] = even[7] + even[4] + even[8];odd[8] = even[8] + even[0] + even[5] + even[7] + even[9];odd[9] = even[9] + even[6] + even[8];}}int totalCount = 0;for (int i = 0; i < 10; i++){totalCount += (useOdd == 1) ? even[i] : odd[i];}return totalCount;}#endregion}
}

3 源程序

using System;
using System.Collections;
using System.Collections.Generic;

namespace Legalsoft.Truffer.Algorithm
{
    public static partial class Algorithm_Gallery
    {
        #region 算法1
        private static int MNKP_Solve_Utility(char[,] keypad, int i, int j, int n)
        {
            if (keypad == null || n <= 0)
            {
                return 0;
            }
            if (n == 1)
            {
                return 1;
            }

            int[] row = { 0, 0, -1, 0, 1 };
            int[] col  = { 0, -1, 0, 1, 0 };

            int totalCount = 0;
            for (int move = 0; move < 5; move++)
            {
                int ro = i + row[move];
                int co = j + col[move];
                if (ro >= 0 && ro <= 3 && co >= 0 && co <= 2 && keypad[ro, co] != '*' && keypad[ro, co] != '#')
                {
                    totalCount += MNKP_Solve_Utility(keypad, ro, co, n - 1);
                }
            }
            return totalCount;
        }

        public static int MNKP_Solve(char[,] keypad, int n)
        {
            if (keypad == null || n <= 0)
            {
                return 0;
            }
            if (n == 1)
            {
                return 10;
            }

            int totalCount = 0;
            for (int i = 0; i < 4; i++) 
            {
                for (int j = 0; j < 3; j++) 
                {
                    if (keypad[i, j] != '*' && keypad[i, j] != '#')
                    {
                        totalCount += MNKP_Solve_Utility(keypad, i, j, n);
                    }
                }
            }
            return totalCount;
        }
        #endregion

        #region 算法2
        public static int MNKP_Solve_2th(char[,] keypad, int n)
        {
            if (keypad == null || n <= 0)
            {
                return 0;
            }
            if (n == 1)
            {
                return 10;
            }
            int[] row = { 0, 0, -1, 0, 1 };
            int[] col = { 0, -1, 0, 1, 0 };

            int[,] count = new int[10, n + 1];

            for (int i = 0; i < 10; i++)
            {
                count[i, 0] = 0;
                count[i, 1] = 1;
            }

            for (int k = 2; k <= n; k++)
            {
                for (int i = 0; i < 4; i++) 
                {
                    for (int j = 0; j < 3; j++) 
                    {
                        if (keypad[i, j] != '*' && keypad[i, j] != '#')
                        {
                            int num = keypad[i, j] - '0';
                            count[num, k] = 0;

                            for (int move = 0; move < 5; move++)
                            {
                                int ro = i + row[move];
                                int co = j + col[move];
                                if (ro >= 0 && ro <= 3 && co >= 0 && co <= 2 && keypad[ro, co] != '*' && keypad[ro, co] != '#')
                                {
                                    int nextNum = keypad[ro, co] - '0';
                                    count[num, k] += count[nextNum, k - 1];
                                }
                            }
                        }
                    }
                }
            }

            int totalCount = 0;
            for (int i = 0; i < 10; i++)
            {
                totalCount += count[i, n];
            }
            return totalCount;
        }
        #endregion

        #region 算法3
        public static int MNTP_Solve_3th(char[,] keypad, int n)
        {
            if (keypad == null || n <= 0)
            {
                return 0;
            }
            if (n == 1)
            {
                return 10;
            }
            int[] odd = new int[10];
            int[] even = new int[10];

            int useOdd = 0;
            for (int i = 0; i < 10; i++)
            {
                odd[i] = 1;
            }

            for (int j = 2; j <= n; j++)
            {
                useOdd = 1 - useOdd;

                if (useOdd == 1)
                {
                    even[0] = odd[0] + odd[8];
                    even[1] = odd[1] + odd[2] + odd[4];
                    even[2] = odd[2] + odd[1] + odd[3] + odd[5];
                    even[3] = odd[3] + odd[2] + odd[6];
                    even[4] = odd[4] + odd[1] + odd[5] + odd[7];
                    even[5] = odd[5] + odd[2] + odd[4] + odd[8] + odd[6];
                    even[6] = odd[6] + odd[3] + odd[5] + odd[9];
                    even[7] = odd[7] + odd[4] + odd[8];
                    even[8] = odd[8] + odd[0] + odd[5] + odd[7] + odd[9];
                    even[9] = odd[9] + odd[6] + odd[8];
                }
                else
                {
                    odd[0] = even[0] + even[8];
                    odd[1] = even[1] + even[2] + even[4];
                    odd[2] = even[2] + even[1] + even[3] + even[5];
                    odd[3] = even[3] + even[2] + even[6];
                    odd[4] = even[4] + even[1] + even[5] + even[7];
                    odd[5] = even[5] + even[2] + even[4] + even[8] + even[6];
                    odd[6] = even[6] + even[3] + even[5] + even[9];
                    odd[7] = even[7] + even[4] + even[8];
                    odd[8] = even[8] + even[0] + even[5] + even[7] + even[9];
                    odd[9] = even[9] + even[6] + even[8];
                }
            }

            int totalCount = 0;
            for (int i = 0; i < 10; i++)
            {
                totalCount += (useOdd == 1) ? even[i] : odd[i];
            }
            return totalCount;
        }
        #endregion
    }
}
 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

迷不迷糊?前后端、三层架构和MVC傻傻分不清

现在的项目都讲究前后端分离&#xff0c;那到底什么是前后端&#xff0c;前后端和以前的MVC以及三层架构啥关系呢&#xff1f;今天就这个问题展开一下&#xff0c;方面后面的学习&#xff0c;因为前面讲的jsp、servlet和javabean根据实例&#xff0c;基本上有一个框架的理解了&…

经纬恒润线控制动系统,新能源智能汽车的未来标配

随着汽车电动化、智能化的发展&#xff0c;制动系统迎来新一轮变革。在新能源车型尤其是新能源智能汽车中&#xff0c;智能底盘系统在底盘融合控制、整车安全方面重要性越来越高&#xff0c;线控制动属于智能底盘的重要部分&#xff0c;凭借着快速响应和精确执行的优势&#xf…

YOLOV9论文解读

代码&#xff1a;https://github.com/WongKinYiu/yolov9论文&#xff1a;https://arxiv.org/abs/2402.1361本文提出可编程梯度信息(PGI)和基于梯度路径规划的通用高效层聚合网络(GELAN)&#xff0c;最终铸成YOLOv9目标检测全新工作&#xff01;性能表现SOTA&#xff01;在各个方…

PCL中的点云分割模型的部分常用参数含义

PCL中的SacModel类别常用参数含义 1、SACMODEL_PLANE2、SACMODEL_LINE&#xff08;三维直线&#xff09;3、SACMODEL_CIRCLE2D&#xff08;二维圆&#xff09;4、SACMODEL_CIRCLE3D&#xff08;三维圆&#xff09;5、SACMODEL_SPHERE&#xff08;球&#xff09;6、SACMODEL_CYL…

《数字图像处理(MATLAB版)》相关算法代码及其分析(2)

目录 1 将8连通边界转换为4连通边界 1.1 移除对角线转折 1.2 插入额外像素 2 将边界信息转换为二进制图像 2.1 函数定义 2.2 参数处理和验证 2.3 默认大小参数设置 2.4 根据参数调整边界位置 2.5 生成二进制图像 2.6 错误处理 3 对二值图像边界的跟踪和提取 3.1 函…

Mybatis学习记录

Mybatis学习记录 1.快速开始示例1.1 什么是MyMyBatis&#xff1f;1.2 代码示例 2.基本使用2.1 #{}和${} 2.2 参数传入2.2.1 概念说明2.2.2 单个简单类型2.2.3 实体类型2.2.4 零散简单数据类型2.2.5 Map类型 2.3 返回值2.3.1 单个简单类型2.3.2 实体类型2.3.3 Map类型2.3.4 List…

java 版本企业招标投标管理系统源码+功能描述+tbms+及时准确+全程电子化

功能描述 1、门户管理&#xff1a;所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含&#xff1a;招标公告、非招标公告、系统通知、政策法规。 2、立项管理&#xff1a;企业用户可对需要采购的项目进行立项申请&#xff0c;并提交审批&#xff0c;查看所…

基于MVO优化的Bi-LSTM多输入回归预测(Matlab)多元宇宙算法优化长短期神经网络回归预测

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、算法介绍&#xff1a; 四、完整程序下载&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于Matlab平台编译&am…

探索Java开发面试笔记:以听为目的,助力编程技术提升与面试准备

文章目录 一、制作背景介绍二、 Java开发面试笔记&#xff1a;为你的编程之路加速2.1 公众号主题和目标读者群体2.2 为什么面试笔记对于提高编程视野和技术至关重要2.3 親測效率 三、形式案例3.1 文章形式3.2 手机案例3.3 电脑案例 一、制作背景介绍 做公众号的背景&#xff1a…

【LeetCode:98. 验证二叉搜索树 + 递归】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

就业班 2401--3.1 Linux Day9--文件查找和压缩

一、文件查找与打包压缩 grep: 文件内容过滤 [rootqfedu.com ~]# grep root /etc/passwd #从/etc/passwd文件中过滤root字段 grep ^root root$ root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin 查找命令 [rootqfedu.com ~]# which ls ali…

【基于HTML5的网页设计及应用】——float实现页面布局

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

Java基础-运算符,表达式和语句

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 一、Java 运算符 算术运算符 关系运算符 位运算符 逻辑运算符 赋值运算符 条件运算符&#xff…

游戏寻路之A*算法(GUI演示)

一、A*算法介绍 A*算法是一种路径搜索算法,用于在图形网络中找到最短路径。它结合了Dijkstra算法和启发式搜索的思想,通过综合利用已知的最短路径和估计的最短路径来优化搜索过程。在游戏自动寻路得到广泛应用。 二、A*算法的基本思想 在图形网络中选择一个起点和终点。维护…

常用的17个运维监控系统(必备知识)

1. Zabbix Zabbix 作为企业级的网络监控工具&#xff0c;通过从服务器&#xff0c;虚拟机和网络设备收集的数据提供实时监控&#xff0c;自动发现&#xff0c;映射和可扩展等功能。 Zabbix的企业级监控软件为用户提供内置的Java应用服务器监控&#xff0c;硬件监控&#xff0c…

Python web框架fastapi中间件的使用,CORS跨域详解

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;Fastapi 景天的主页&#xff1a;景天科技苑 文章目录 fastapi中间件与CORS1、中间件1.创建中间件方法2.中间件里面添加响应头…

跨地域传文件时 面临的安全、效率等问题要如何解决?

近年来&#xff0c;企业在异国、异地设立分支机构的越来越多&#xff0c;在日常经营中&#xff0c;企业总部和分支机构间存在平行、垂直及互相交叉的管理模式和业务往来需求&#xff0c;因此&#xff0c;大型企业存在必然的跨地域传文件场景&#xff0c;比如跨地理域文件交换、…

揭秘麦肯锡的方法:产品经理解决问题指南

您是否想知道世界上最成功的产品经理如何始终如一地提供不仅满足而且超出预期的解决方案&#xff1f;秘密可能就在于世界上最负盛名的咨询公司之一麦肯锡公司所磨练的方法论。本文深入探讨了麦肯锡的问题解决流程&#xff0c;该流程专为希望提升水平的产品经理量身定制。 01. 麦…

2024最新AI大模型产品汇总

文章目录 1. 写在前面2. 效率工具3. 聊天机器人4. 应用开发工具5. Prompt工具与社区6. 通用基础大模型7. 训练框架8. 开源数据集9. 推理与部署平台及工具 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致…

Flutter整体框架

Flutter整体框架由三部分组成&#xff1a;Framework、Engine和Embedder。 Framework Framework提供了一个用 Dart 语言编写的现代、反应式框架&#xff0c;由许多抽象的层级组成。它包括一套丰富的布局、动画、绘制、手势UI组件及配套代码&#xff0c;以及更基础的异步、文件、…