日常练习题

题目来源:力扣(LeetCode)
题目链接:https://leetcode-cn.com/problems/android-unlock-patterns

【练习题】

我们都知道安卓有个手势解锁的界面,是一个 3 x 3 的点所绘制出来的网格。用户可以设置一个 “解锁模式” ,通过连接特定序列中的点,形成一系列彼此连接的线段,每个线段的端点都是序列中两个连续的点。如果满足以下两个条件,则 k 点序列是有效的解锁模式:

解锁模式中的所有点 互不相同 。
假如模式中两个连续点的线段需要经过其他点的 中心 ,那么要经过的点 必须提前出现 在序列中(已经经过),不能跨过任何还未被经过的点。
例如,点 5 或 6 没有提前出现的情况下连接点 2 和 9 是有效的,因为从点 2 到点 9 的线没有穿过点 5 或 6 的中心。
然而,点 2 没有提前出现的情况下连接点 1 和 3 是无效的,因为从圆点 1 到圆点 3 的直线穿过圆点 2 的中心。
以下是一些有效和无效解锁模式的示例:

无效手势:[4,1,3,6] ,连接点 1 和点 3 时经过了未被连接过的 2 号点。
无效手势:[4,1,9,2] ,连接点 1 和点 9 时经过了未被连接过的 5 号点。
有效手势:[2,4,1,3,6] ,连接点 1 和点 3 是有效的,因为虽然它经过了点 2 ,但是点 2 在该手势中之前已经被连过了。
有效手势:[6,5,4,1,9,2] ,连接点 1 和点 9 是有效的,因为虽然它经过了按键 5 ,但是点 5 在该手势中之前已经被连过了。
给你两个整数,分别为 ​​m 和 n ,那么请返回有多少种 不同且有效的解锁模式 ,是 至少 需要经过 m 个点,但是 不超过 n 个点的。

两个解锁模式 不同 需满足:经过的点不同或者经过点的顺序不同。

示例 1:

输入:m = 1, n = 1
输出:9
示例 2:

输入:m = 1, n = 2
输出:65

【分析】:

考虑经过的点,以及不同的经过点数,采用深度遍历。

该题代码来源:

作者:dangerous_le
链接:https://leetcode-cn.com/problems/android-unlock-patterns/solution/vivode-bi-shi-ti-by-wei-zhi-meng/

#include <stdio.h>

int Dg(int dc[][10],int drop[],int begin,int finish){
	//传参: dc对称跳点  drop经过点 begin开始点 finish结束点 
	if (finish == 0) return 1; 
	int all = 0;
	drop[begin] = 1; // 记录开始点 
	for(int i = 1;i<=9;i++)
	{
		// 在确定 没有经过该点 并且 俩点之间已经经过跳点 
		if((drop[i]-1) && (drop[dc[begin][i]] || dc[begin][i] == 0))
		{
			// 开始深度遍历 并记录 
			all += Dg(dc,drop,i,finish-1);
		}
	}
	drop[begin] = 0;
	return all;
}

int Array(int m,int n){
	int all = 0; //计数 
	int dc[10][10] = {0}; // 记录跳跃点数 如 1到3 之间跳跃 2 
	int drop[10] = {0};  // 记录是否经过这个点 
	dc[1][3] = dc[3][1] = 2;
	dc[1][7] = dc[7][1] = 4;
	dc[7][9] = dc[9][7] = 8;
	dc[3][9] = dc[9][3] = 6;
	dc[1][9] = dc[3][7] = dc[9][1] = dc[7][3] = 5;
	dc[2][8] = dc[4][6] = dc[8][2] = dc[6][4] = 5;
	for(int i=m;i<=n;i++)
	{
		// 1 3 7 9 、2 4 6 8都存在对称 所以当求出 1和2 *4便可以得出其他的可能数
		// 5没有对称 所以单独 运行 
		all += Dg(dc,drop,1,i-1)*4;
		all += Dg(dc,drop,2,i-1)*4;
		all += Dg(dc,drop,5,i-1);
	}
	return all;
}

int main(){
	int m=0,n=0;
	scanf("%d %d",&m,&n);
	printf("%d",Array(m,n));
} 

【思考】

练习该题,并借鉴了大佬的代码,使用c语言再打一遍,再一步步看完代码后感觉受益匪浅,希望以后也能打出这样的代码。

注:如有侵权请联系我,删除该文章。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值