• XTU-OJ 1331-密码


    题目描述

    Eric喜欢使用数字1,2,3,4作为密码,而且他有个怪癖,相邻数字不能相同,且相差不能超过2。当然只用数字做密码,会比较弱,Eric想知道当长度为n时,这样的密码有多少种?

    输入

    第一行是一个整数T(1≤T≤45),表示样例的个数。 每行一个样例,为整数n(1≤T≤45)。

    输出

    每行输出一个样例的结果。

    样例输入

    5
    1
    2
    3
    4
    5
    

    样例输出

    4
    10
    26
    66
    170

    解题思路:这题就用递推的方法来解。 何为递推?顾名思义,就是一步一步的推理~~,答案是推出来的。 然后从  相邻数字不能相同,且相差不能超过2  这个条件入手。

    当长度n==1时,密码有几种情况? 秒答:1、2、3、4 四种情况,

    那长度n==2时,有几种情况?这时就已经要开始递推了。当第一位数字是1,第二位数字可为 2、3,当第一位数字是2,第二位数字可为 1、3、4,当第一位数字是3,第二位数字可为 1、2、4,当第一位数字是4,第二位数字可为 2、3。   这是一共就是 2+3+3+2种情况。

    此时如果你能具有一定的敏感性,懂得逆向思考一下,这题已经解决了。如果我先规定第2位的数字,然后再考虑前面的情况。规定是1,那第一位只能是2、3,规定是2,那第一位只能是1、3、4........

    推广:先规定第n位的数字,然后找到符合条件的第n-1位数和它匹配。 那就是 第n位是1的种类数等于,第n-1位是2的种类数+第n-1位是3的种类数;第n位是2的种类数等于,第n-1位是1的种类数+第n-1位是3的种类数+第n-1位是4的种类数........

    现在你是否能得出答案。(注意这种情况数字都很大,往往要考虑是否会爆int)

    AC代码:

    1. #include
    2. int T,N;
    3. __int64 ak47[50][5];
    4. __int64 ans;
    5. void slove()
    6. {
    7. ak47[1][1] = ak47[1][2] = ak47[1][3] = ak47[1][4] = 1;
    8. for (int i = 2; i <= 45; i ++)
    9. {
    10. ak47[i][1] = ak47[i-1][2]+ak47[i-1][3];
    11. ak47[i][2] = ak47[i-1][1]+ak47[i-1][3]+ak47[i-1][4];
    12. ak47[i][3] = ak47[i-1][1]+ak47[i-1][2]+ak47[i-1][4];
    13. ak47[i][4] = ak47[i-1][2]+ak47[i-1][3];
    14. }
    15. }
    16. int main()
    17. {
    18. slove(); // 递推
    19. scanf("%d",&T);
    20. while ( T --)
    21. {
    22. scanf("%d",&N);
    23. ans = ak47[N][1]+ak47[N][2]+ak47[N][3]+ak47[N][4];
    24. printf("%I64d\n",ans);
    25. }
    26. return 0;
    27. }

  • 相关阅读:
    基于STM32设计的便携式心电信号监测系统
    RabbitMQ持久化
    STI比赛任务一:【智能问答baseline】
    Java线程
    3. 【containerd】image 什么时候会被垃圾回收
    Spring面试大全——(有这一篇就够了)
    基于AT89C51的出租车计价器设计(全套毕设资料)
    磁盘空间不够引发的控制录像程序崩溃到后端的解决方式
    C语言指针详解
    【老生谈算法】matlab实现蒙特卡罗定积分源码——蒙特卡罗定积分
  • 原文地址:https://blog.csdn.net/Jay_is_Chou/article/details/133840168