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

news2025/1/12 1:39:54

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 算法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
    }
}

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.coloradmin.cn/o/1493423.html

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

相关文章

Guava处理异常

guava由Google开发&#xff0c;它提供了大量的核心Java库&#xff0c;例如&#xff1a;集合、缓存、原生类型支持、并发库、通用注解、字符串处理和I/O操作等。 异常处理 传统的Java异常处理通常包括try-catch-finally块和throws关键字。 遇到FileNotFoundException或IOExce…

LocalDateTime类常用的方法介绍

Java 8引入了新的日期和时间API&#xff0c;其中包括LocalDateTime类&#xff0c;它表示没有时区信息的日期和时间。这个类是不可变的&#xff0c;并且线程安全。LocalDateTime类提供了大量的方法来处理日期和时间&#xff0c;包括格式化、转换和计算。 创建LocalDateTime对象 …

Android耗电分析之Battery Historian工具使用

Battery-Historian是谷歌推出的一款专门分析Bugreport的工具&#xff0c;是谷歌在2015年I/O大会上推出的一款检测运行在android5.0(Lollipop)及以后版本的设备上电池的相关信息和事件的工具&#xff0c;是一款对于分析手机状态&#xff0c;历史运行情况很好的可视化分析工具。 …

第106讲:Mycat实践指南:范围分片下的水平分表详解

文章目录 1.Mycat水平拆分的分片规则2. Mycat水平拆分之范围分片2.1.使用范围分片水平分表的背景2.2.水平分表范围分片案例2.3.准备测试的表结构2.4.配置Mycat实现范围分片的水平分表2.4.1.配置Schema配置文件2.4.2.配置Rule分片规则配置文件2.4.3.配置Server配置文件2.4.4.重启…

牛客网 华为机试 取近似值

本题是要实现四舍五入。我们采用float的数据类型&#xff0c;因为这样数据精度更高。然后我们可以把得到的数据0.5&#xff0c;然后再转换成int数据类型&#xff0c;因为转换成int数据类型的时候是向下取整的&#xff0c;比如4.9转换成int就是4&#xff0c;4.2转换成int也是4。…

Python错题集-7:DeprecationWarning: Conversion of an array with ndim(被弃用警告)

1问题描述 DeprecationWarning: Conversion of an array with ndim > 0 to a scalar is deprecated, and will error in future. Ensure you extract a single element from your array before performing this operation. (Deprecated NumPy 1.25.) X[i] np.random.nor…

LCR 188. 买卖芯片的最佳时机

解题思路&#xff1a; 动态规划 方法一&#xff1a;常规解法 class Solution {public int bestTiming(int[] prices) {int n prices.length;if (n 0) return 0;int[] dp new int[n];int cost prices[0];for (int i 1; i < n; i) {cost Math.min(cost, prices[i]);dp…

Unity类银河恶魔城学习记录8-2 p78.Improving black with clone creating源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作【Unity教程】从0编程制作 Blackhole_Hotkey_Controller.cs using System.Collections; using System.Collectio…

Dell R620中文手册下载

poweredge-r620_owners-manual_zh-cn.pdf https://url20.ctfile.com/f/36743220-1030280698-8d9322?p2024 (访问密码: 2024)

为什么我建议你2024年一定要入局鸿蒙?

自去年发布现象级“爆款”手机Mate 60后&#xff0c;华为就备受关注。小灰作为一枚程序员&#xff0c;关注的重心更偏向于技术。华为手机搭载的国产自研的鸿蒙操作系统&#xff08;HarmonyOS&#xff09;&#xff0c;已经成为一个业界的里程碑&#xff0c;是我国国产技术自主化…

ChatGPT Plus 自动扣费失败,如何续订

ChatGPT Plus 自动扣费失败&#xff0c;如何续订 如果您的 ChatGPT Plus 订阅过期或扣费失败&#xff0c;本教程将指导您如何重新订阅。 本周更新 ChatGPT Plus 是一种每月20美元的订阅服务。扣费会自动进行&#xff0c;如果您的账户余额不足&#xff0c;OpenAI 将在一次扣费…

C语言写学生信息管理系统

说明:本博文来自CSDN-问答板块,题主提问。 需要:用C语言设计一个学生信息管理系统(尽量不使用指针),学生信息包括学号,姓名,数学成绩,C语言成绩,英语成绩和每个学生的总成绩这几项。系统要实现如下几个功能:1.添加学生2.删除学生3.修改学生信息4.查询学生信息5进行学…

C#,无监督的K-Medoid聚类算法(K-Medoid Algorithm)与源代码

1 K-Medoid算法 K-Medoid&#xff08;也称为围绕Medoid的划分&#xff09;算法是由Kaufman和Rousseeuw于1987年提出的。中间点可以定义为簇中的点&#xff0c;其与簇中所有其他点的相似度最小。 K-medoids聚类是一种无监督的聚类算法&#xff0c;它对未标记数据中的对象进行聚…

安装/升级 gcc

文章目录 查看当前 gcc 版本查看 yum 软件库 gcc 版本列表下载最新版本安装 查看当前 gcc 版本 查看 yum 软件库 gcc 版本列表 只有一个4.8的版本&#xff0c;过旧 下载最新版本 wget https://ftp.gnu.org/gnu/gcc/gcc-13.2.0/gcc-13.2.0.tar.gz 安装 ./configure 报错 提示…

【深圳五兴科技】Java后端面经

本文目录 写在前面试题总览1、java集合2、创建线程的方式3、对spring的理解4、Spring Boot 和传统 Spring 框架的一些区别5、springboot如何解决循环依赖6、对mybatis的理解7、缓存三兄弟8、接口响应慢的处理思路9、http的状态码 写在前面 关于这个专栏&#xff1a; 本专栏记录…

基于51单片机的电子秒表Protues仿真设计

目录 一、设计背景 二、实现功能 三、仿真结果 四、源程序 一、设计背景 随着科技的不断发展&#xff0c;电子设备在我们生活中扮演着愈加重要的角色。这些电子设备不仅使我们的生活更加便利&#xff0c;还帮助我们提高工作效率和精确度。其中&#xff0c;电子秒表是常用的计…

如何配置JDK的环境变量(简单灵活易懂)

前言&#xff1a; 开始学习java的小伙伴们一定都备一件事困扰过&#xff0c;那就是jdk的环境变量的配置&#xff0c;搞不懂为啥要配置环境变量&#xff0c;到底有啥子用&#xff1f;接下来小编带大家配置一下 配置环境变量的作用&#xff1f; Path&#xff1a;当用javac、jav…

redis 缓存击穿问题(互斥锁,逻辑过期)

1、缓存击穿问题 缓存击穿问题:一个被高并发访问并且缓存重建业务较复杂的key突然失效了&#xff0c;无数的请求访问会在瞬间给数据库带来巨大的冲击。 场景:假设线程1在查询缓存之后&#xff0c;本来应该去查询数据库&#xff0c;然后把这个数据重新加…

Java学习笔记002——类的修饰符

在Java语言中&#xff0c;类的访问修饰符决定了其它类能够访问该类的方式。类有如下4种访问修饰符&#xff0c;在创建类时用于类的声明&#xff1a; 1、public: 当一个类被声明为public时&#xff0c;它可以从任何其他类中被访问&#xff0c;无论这些类位于哪个包中。通常&am…

探索设计模式的魅力:深入解析解释器模式-学习、实现与高效使用的全指南

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;并且坚持默默的做事。 探索设计模式的魅力&#xff1a;解析解释器模式学习、实现与高效使用全指南 文章目录 一、案…