枚举三位数的密码

举报
用户已注销 发表于 2021/11/19 05:08:24 2021/11/19
【摘要】 密码箱是三位数的密码,也就是一共有1000种情况。 我曾经用枚举法找回忘记的密码,试了900多个才成功,大约10分钟。 今天在机房看到主机都是用密码锁锁起来的,仔细思考了一番,发现这里面蕴含着一些规律。   最普通的枚举法,自然是从000到999枚举了。 这种枚举法有2个规律 规律一:百位、十位、个位每次最多只变化...

密码箱是三位数的密码,也就是一共有1000种情况。

我曾经用枚举法找回忘记的密码,试了900多个才成功,大约10分钟。

今天在机房看到主机都是用密码锁锁起来的,仔细思考了一番,发现这里面蕴含着一些规律。

 

最普通的枚举法,自然是从000到999枚举了。

这种枚举法有2个规律

规律一:百位、十位、个位每次最多只变化1(从9到0也算变化1)

比如说,从9到10,百位不变,十位变化1,个位变化1

规律二:个位每次都变,即变化了999次,十位变化99次,百位只变化9次,一共是1107次

 

有没有变化更少的方案呢?

我想到了2048的策略,同样的,枚举密码也可以采用这种来回绕的方法

0 1 2 3 4 5 6 7 8 9 19 18 17 16 15 14 13 12 11 10 

20 21 22 23 24 25 26 27 28 29 39 38 37 36 35 34 33 32 31 30 

40 41 42 43 44 45 46 47 48 49 59 58 57 56 55 54 53 52 51 50 

60 61 62 63 64 65 66 67 68 69 79 78 77 76 75 74 73 72 71 70 

80 81 82 83 84 85 86 87 88 89 99 98 97 96 95 94 93 92 91 90

可以发现,对于这种枚举法,对于前面这些数来说,

每次都只有1位变化了1,另外2位不变。

 

如果后面是从100到190,200到290......900到990,这样的话,

只有在百位发生变化的时候才会有2位发生了变化。

所以,一共是发生了1008次变化。

计算变化次数的代码:

 


  
  1. #include<iostream>
  2. #include<iomanip>
  3. using namespace std;
  4. int f(int a, int b)
  5. {
  6. return (a % 10 != b % 10) + (a / 10 % 10 != b / 10 % 10) + (a / 100 != b / 100);
  7. }
  8. int map(int n)
  9. {
  10. if (n / 10 % 2 == 0)return n;
  11. int s = n % 10;
  12. return n - s + 9 - s;
  13. }
  14. int main()
  15. {
  16. int s = 0;
  17. for (int i = 0; i < 999; i++)
  18. {
  19. cout << setw(4) << map(i);
  20. s += f(map(i), map(i + 1));
  21. }
  22. cout << endl << s;
  23. return 0;
  24. }

这里的map就是一个计算数列通项的函数

结果果然也是1008

 

不过这还不是最好的结果。

最好的结果,是根据百位再度来回绕。

代码也很好改,只需要用复合函数就可以了

代码:

 


  
  1. #include<iostream>
  2. #include<iomanip>
  3. using namespace std;
  4. int f(int a, int b)
  5. {
  6. return (a % 10 != b % 10) + (a / 10 % 10 != b / 10 % 10) + (a / 100 != b / 100);
  7. }
  8. int map(int n)
  9. {
  10. if (n / 10 % 2 == 0)return n;
  11. int s = n % 10;
  12. return n - s + 9 - s;
  13. }
  14. int map2(int n)
  15. {
  16. if (n / 100 % 2 == 0)return map(n);
  17. int s = n % 100;
  18. return map(n - s + 99 - s);
  19. }
  20. int main()
  21. {
  22. int s = 0;
  23. for (int i = 0; i < 999; i++)
  24. {
  25. cout << setw(4) << map2(i);
  26. s += f(map2(i), map2(i + 1));
  27. }
  28. cout << endl << s;
  29. return 0;
  30. }

而且很有意思的是,map2和map差不多

 

运行结果:

很明显,这个就是变化最少的方案了,每2个数之间,都只有一位发生了变化。

 

当然,如果手动枚举密码的话,还是最普通的比较靠谱。

文章来源: blog.csdn.net,作者:csuzhucong,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/nameofcsdn/article/details/52811996

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。