判断手势_手势密码有几种?

ca762103fa6c7a869e79a000191db568.png

前几天想到一个有趣的问题,我们每个手机都可以设置手势密码,那么手势密码一共有几种呢?

我们先了解下手势密码设置的规则:密码必须不小于4个点,点在第一次经过时不允许被跳过。

c1ef5662880e1987e2a48da0b366ad95.png

如图,我们把每个点编上序号。

则以下这种是不合法的。

8261542b686e90a7cedb5dd7d54186f5.png

5被连接了两次

51e78ff1713fbde595739668e1e6930c.png

这种是合法的,因为5被跳过了。而被跳过的点不被记为总点数。

用数字表示的话,例如1923则不能为四个点连接的情况,因为1和9之间有5,所以实际上是15923。

如果用纯理性分析的话,这无疑是个极为复杂的数学题,很多数学技巧似乎都被限制住。但是,我们有计算机这个无比强大的工具。这里,我选择用C语言处理。

宏定义

#define SIZE 10000
#define XSIZE 5
#define SIZEX 11111

以五个数字组成的密码举例,SIZE为

,XSIZE为位数,SIZEX为起始的穷举数字。这样通过改变三个变量,能得到不同的组合的个数。

主函数部分

void main(){
 int n = 0;
 int i = SIZEX, j = 0;
    for (i; i < SIZE*10; i++) {
       if(check(i)) n++;
	}
       printf("%d",n);
}

主函数部分十分简单,就是简单的循环遍历。

check函数部分

int check(int i)
{
   int k = 0, j = SIZE;
   int a[XSIZE];
     while (k<XSIZE) {
	 a[k] = i / j;
	 i = i - a[k] * j;
	 j = j / 10;
	 k++;
	}
    for (k=0; k < XSIZE; k++) {
      for (j = k + 1; j < XSIZE; j++) {
	 if (a[k] == a[j]) return 0;
	   }
	  if (a[k] == 0) return 0;
      }
    for ( k = 0; k+1< XSIZE; k++){
       if ((a[k] + a[k + 1]) == 4) {
	   if (!check1(a, k)) return 0;
	  }
	if ((a[k] + a[k + 1]) == 10) {
	   if (!check1(a, k)) return 0;
	  }
	if ((a[k] + a[k + 1]) == 16) {
	   if (!check1(a, k)) return 0;
	  }
	 if (a[k] - a[k + 1] == 6 || a[k + 1] - a[k] == 6) {
	   if (!check1(a, k)) return 0;
	  }
    }
     return 1;
}

该函数大致分为三个部分,第一部分,对传入的i分离i的各个位数的数字,并存入数组中。第二部分,设置两个循环判断数组中是否有相同的数字,第三部分,设置循环,遍历相邻的两个数字,判断这两个数字是否满足可能非法的条件,即两个数字间是否包含第三个数字,然后传入check1函数,判断两个数字前是否有中间包含的第三个数字,存在的话说明是合法的。

check1函数

int check1(int *a, int k) {
	for (int i = 0; i < k; i++) {
		if (a[i] == (a[k] + a[k + 1]) / 2) return 1;
	}
	return 0;
}

结论

运行程序,发现各个数字的个数,其中

4位的有1624

5位的有7152

6位的有26016

7位的有72912

8位的有140704

9位的有140704个

总共有389112种!

值得一提的是,6位以下的个数甚至每到10000种,所以设置密码最好设置6位以上的,当然不怕忘记的话,可以设置9位的变态密码。

完。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值