2020VIVO春招编程题手机解锁图案

12 篇文章 0 订阅
10 篇文章 0 订阅

菜鸡看到这个题目后,想法很多,实现感觉挺复杂。。网上找的C++的实现都不太靠谱。看到一篇java实现的感觉逻辑清晰,为他点个赞,稍微改下C++。

**> 题目

现有一个 3x3 规格的 Android 智能手机锁屏程序和两个正整数 m 和 n ,请计算出使用最少m 个键和最多
n个键可以解锁该屏幕的所有有效模式总数。 其中有效模式是指: 1、每个模式必须连接至少m个键和最多n个键; 2、所有的键都必须是不同的;
3、如果在模式中连接两个连续键的行通过任何其他键,则其他键必须在模式中选择,不允许跳过非选择键(如图);
4、顺序相关,单键有效(这里可能跟部分手机不同)。**

在这里插入图片描述
输入:m,n
代表允许解锁的最少m个键和最多n个键
输出:
满足m和n个键数的所有有效模式的总数
原文:JAVA实现

改变上主要是数组定义,已经数组需要初始化;(不赋0初始化总是出错,有专业同学解释下吗)

#include<iostream>
using namespace std;
class Solution {
public:
	//用来存储两个键相连经过其他键情况
	//vector<vector<int>>arr=
	int(*arr)[10]=new int [10][10];
	
	//动态初始化boolean数组 默认值为false
	bool *select=new bool [10];

	int solution(int m, int n) {
		for (int i = 0; i <= 9; i++)
		{
			select[i] = false;
			for (int j = 0; j <= 9; j++)
			{
				arr[i][j] = 0;
			}
		}
		//三行 1和3连线必须2已经连入
		arr[1][3] = arr[3][1] = 2;
		arr[4][6] = arr[6][4] = 5;
		arr[7][9] = arr[9][7] = 8;
		//三竖
		arr[1][7] = arr[7][1] = 4;
		arr[2][8] = arr[8][2] = 5;
		arr[9][3] = arr[3][9] = 6;
		//两条对角线
		arr[1][9] = arr[9][1] = 5;
		arr[3][7] = arr[7][3] = 5;
		//用于判断是否可以可以连入 二位数组 int默认值为0 没有跨节点下标为0就是true
		select[0] = true;

		if (m < 0 || n < m) {
			return 0;
		}
		// 1 3 7 9情况合并  2 4 6 8情况合并 5一种情况
		int total = 4 * calculateCount(m, n, 1, 1) + 4 * calculateCount(m, n, 2, 1)
			+ calculateCount(m, n, 5, 1);
		return total;
	}

	int calculateCount(int min, int max, int start, int len) {
		int count = 0;
		if (len > max) {
			return 0;
		}
		if (len >= min) {
			count++;
		}//这里意味着连接到当前点且深度满足要求时计数+1;在进入本次判定前其实已经判定了不存在跨越连接的情况,所以我觉得其实可以将这几次判断合并,这里这样做的原因主要是递归后便于区分“能不能连(不存在13式的跨越)”和“有没有必要连(只求1步和两步的连法)”
		select[start] = true;
		for (int i = 1; i < 10; i++) {
			//当前节点start没有被选人 并且开始节点start到当前节点i不是跨节点连接
			if (!select[i] && select[arr[start][i]]) {
				count = count + calculateCount(min, max, i, len + 1);
			}
		}
		select[start] = false;
		return count;
	}
};
int main() {
	Solution test;
	cout << test.solution(1, 2) << endl;
	system("pause");
	return 0;
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值