vivo2020春招笔试编程题(下)

本文介绍笔者参加过的vivo2020春招笔试编程的第三题。

第三题:手机屏幕解锁模式

题干

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

输入:m,n
代表允许解锁的最少m个键和最多n个键
输出:
满足m和n个键数的所有有效模式的总数

例:
输入:1,2
输出:65
说明:输入m=1,n=2,表示最少1个键,最多2个键,符合要求的键数是1个键和2个键,其中1个键的有效模式有9种,两个键的有效模式有56种,所以最终有效模式总数是9+56=65种,最终输出65

时间限制:C/C++ 1秒,其他语言2秒;空间限制:C/C++ 256M,其他语言512M

vivo2020春招笔试编程题(下)_第1张图片

敝人方案

我懵了,以下代码在n=3的时候就错了,n=1或2的情况没有问题,想了想确实有问题,在计算无效连接时多算了,但是不知道怎么解决。。。

public static int numberOfConnections(int m, int n) {
	int res = 0;
	int keys = 9;
	for(int i = m; i <= n; i++) {
		//计算全部连接
		int fullCons = 1; //全部连接,包含非选择键
		int tempKeys = keys;
		for(int j = 0; j < i; j++) {
			fullCons = fullCons * tempKeys;
			tempKeys--;
		}
		//计算无效的连接(算法错误)
		int redundant = 0; 
		for(int k = 0; k < i - 1; k++) { //包含i个键,就有i-1条连接
			int left = k; //利用双指针
			int right = i - 2 - k;
			if(left == 0 && right == 0) //i=2时成立
				redundant += 8*2; //8条跳过非选择键是禁止的,允许双向所以乘2 
			else {
				tempKeys = keys - 2; //7
				int tempRed = 0;
				if(left > 0){
				tempRed = 8*2;
					while(left > 0) {
						tempRed = tempRed * tempKeys;
						tempKeys--;
						left--;
					}
					redundant += tempRed;
				}
				tempKeys = keys - 2;
				if(right > 0){
					tempRed = 8*2;
					while(right > 0) {
						tempRed = tempRed * tempKeys;
						tempKeys--;
						right--;
					}
					redundant += tempRed;
				}
			}
		}
		res += fullCons - redundant; //有效连接=全部-无效
	}
	return res;
}

目前三道试题可以在牛客网上找到,链接如下:vivo2020届春季校园招聘在线编程考试

敝人一枚菜鸡,望大侠们能指破迷津,留言告知

2020.4.2

你可能感兴趣的:(面试笔试)